drf之apiview请求生命周期,渲染,序列化,orm回顾
一、Django配置回顾
""" 1)应用是否需要在INSTALLED_APPS中注册 在没有使用到app的一些特殊操作时(比如数据库相关),可以不用注册,但是注册后,应用的所有功能都能使用 结论:所有应用都可以完成注册 2)数据库配置(全部在settings文件中完成即可) import pymysql pymysql.install_as_MySQLdb() DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME': '数据库名', 'USER': '账号', 'PASSWORD': '密码', 'HOST': '如果是127.0.0.1,该配置可以省略', "PORT": 3306, # 如果是3306,该配置可以省略 } } 3)路由分发 主路由:将应用自己逻辑相关的路由交给自己处理 from django.conf.urls import url, include urlpatterns = [ # ... url(r'^api/', include('api.urls')), # /api/test/ ] """
二、orm配置回顾
# models.py from django.db import models class User(models.Model): SEX_CHOICES = ((0, '男'), (1, '女')) name = models.CharField(max_length=64, verbose_name='姓名') age = models.IntegerField() height = models.DecimalField(max_digits=5, decimal_places=2, default=0) sex = models.IntegerField(choices=SEX_CHOICES, default=0) # sex = models.CharField(choices=[('0', '男'), ('1', '女')]) icon = models.ImageField(upload_to='icon', default='icon/default.png') # settings.py # root就是将文件夹添加到 os.path 中 MEDIA_ROOT = os.path.join(BASE_DIR, 'media') # url就是配置路由 /路由名/ MEDIA_URL = '/media/'
from django.views.static import serve
# 暴露文件给前端 主路由最下方
# url(r'^(?P<path>.*)$', serve, {'document_root': '/path/to/my/files/'})
# https://;localhost:8000/media/icon/default.png # icon/default.png => path变量 {'document_root': '/path/to/my/files/'}文件的路径
url(r'^media/(?P<path>.*)', serve, {'document_root': settings.MEDIA_ROOT})
三、APIView请求生命周期
1、重写的as_view方法
""" 1)as_view方法完成路由配置,返回配置函数是 csrf_exempt(view),也就是禁用了csrf认证规则 结论:所有继承APIView的子类,都不受csrf认证规则的限制 2)将请求处理的任务交给dispath方法完成 """
2、重写的dispatch方法
""" 完成了三大核心任务: 1)请求对象的处理:请求渲染模块 2)请求过程的处理:三大认证模块 => 自己代码完成处理 3)请求结果的响应:异常模块处理异常响应 | 响应渲染模块处理正常响应 """
四、请求解析模块
""" 1)二次封装了原生Django的wsgi协议的request对象,并做了向下兼容(原来request对象的内容,用现在的request对象都能访问) 2)将所有拼接参数都放在request.query_params中,将所有数据包参数都放在request.data中 3)路由的有名无名分组的数据还是保存在args和kwargs中 """ # 解析模块可以在settings.py自定义解析配置 REST_FRAMEWORK = { # 解析模块 'DEFAULT_PARSER_CLASSES': [ 'rest_framework.parsers.JSONParser', # json 'rest_framework.parsers.FormParser', # urlencoded 'rest_framework.parsers.MultiPartParser' # form-data ], # 渲染模块 'DEFAULT_RENDERER_CLASSES': [ 'rest_framework.renderers.JSONRenderer', 'rest_framework.renderers.BrowsableAPIRenderer', # 上线后会注释 ], }
- 向下兼容性
def post(self, request, *args, **kwargs): # 向下兼容:原来对象拥有的,现在对象都有 print(type(request)) # apiview二次封装的request drf的 print(type(request._request)) # 原来的request django原生的wsgi
五、响应渲染模块
""" 1)当三大认证模块和自己处理请求的视图逻辑没有出现异常时,会执行响应渲染模块 2)响应的数据会交给渲染模块来完成数据的渲染,渲染方式有两种:Json格式数据渲染、Brower格式数据渲染 """ # 渲染模块可以在settings.py自定义解析配置 REST_FRAMEWORK = { # 渲染模块 'DEFAULT_RENDERER_CLASSES': [ 'rest_framework.renderers.JSONRenderer', # 浏览器渲染,上线后会注释,不然浏览器请求接口就暴露了后台语言 'rest_framework.renderers.BrowsableAPIRenderer', ], }
六、序列化组件
1、单表序列化
models.py
from django.db import models from django.conf import settings # Create your models here. from django.conf import settings class User(models.Model): SEX_CHOICES = ((0, '男'), (1, '女')) name = models.CharField(max_length=64, verbose_name='姓名') password = models.CharField(max_length=64, verbose_name='密码') age = models.IntegerField() height = models.DecimalField(max_digits=5, decimal_places=2) sex = models.IntegerField(choices=SEX_CHOICES, default=0) # sex = models.CharField(choices=[('0', '男'), ('1', '女')]) icon = models.ImageField(upload_to='icon', default='icon/default.png') # 自定义序列化给前台的字段 # 1)可以格式化数据库原有字段的数据 # 2)可以对外隐藏原有数据字段名 # 3)可以直接链表 # 制作插头 @property def gender(self): return self.get_sex_display() # get_sex_display()展示性别 @property def img(self): # print(type(self.icon), self.icon) # res = settings.BASE_URL + settings.MEDIA_URL + str(self.icon) # 或者直接拿name也可以 res = settings.BASE_URL + settings.MEDIA_URL + self.icon.name return res def __str__(self): return self.name
serializers.py
from rest_framework import serializers # 序列化 from . import models class UserModelSerializer(serializers.ModelSerializer): # 配置类 class Meta: # 自定义该序列化类是辅助于那个model类 model = models.User # 设置参与序列化与反序列化字段 # 插拔式:可以选择性返回给前端字段(插头都是在model类中制作) # fields = ['name', 'age', 'height', 'sex', 'icon', 'gender'] fields = ['name', 'age', 'height', 'sex', 'img', 'gender']
views.py
from rest_framework.views import APIView from rest_framework.response import Response from . import models, serializers class UserAPIView(APIView): def get(self, request, *args, **kwargs): pk = kwargs.get('pk') if pk: # 单查 # 1) 数据库交互拿到资源obj或资源objs # 2) 数据序列化成可以返回给前台的json数据 # 3) 将json数据返回给前台 obj = models.User.objects.get(pk=pk) serializer_obj = serializers.UserModelSerializer(obj) return Response(serializer_obj.data) else: # 群查 # 1)数据库交互拿到资源obj或资源objs # 2)数据序列化成可以返回给前台的json数据 # 3)将json数据返回给前台 objs = models.User.objects.all() # 操作多个数据many=True serializer_obj = serializers.UserModelSerializer(objs, many=True) return Response(serializer_obj.data) def post(self, request, *args, **kwargs): # 单增 # 1)从请求request中获取前台提交的数据 # 2)将数据转换成model对象,并完成数据库入库操作 # 3)将入库成功的对象序列化成可以返回给前台的json数据(请求与响应数据不对等:请求需要提交密码,响应一定不展示密码) # 4)将json数据返回给前台 return Response()
Only you can control your future
You're not alone. You still have family,peopel who care for you and want to save you.