Django配置
'''
1.应用是否需要在INSTALLED_APPS中注册取决于是否使用到app的一些特殊操作(如数据库相关),可以不用注册,但是注册后,应用的功能都能使用。
结论:所有应用都注册即可
2.数据库配置:在settings.py中完成即可
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.路由分发
当项目比较庞大时,如果把所有路由匹配关系都写在总路由里,会比较难以管理和维护。所以我们可以将app相关的路由逻辑进行分发。
urlpatterns = [
url(r'^api/',include('api.urls'))
]
'''
ORM配置回顾
models.py
from django.db import models
class User(models.Model):
pass
APIView的请求生命周期
1.APIView类继承了原生Django的View类,并重写了as_view方法
"""
1)as_view方法完成路由配置,返回配置函数是 csrf_exempt(view),也就是禁用了csrf认证规则
结论:所有继承APIView的子类,都不受csrf认证规则的限制
2)将请求处理的任务交给dispath方法完成
"""
2.重写的dispatch方法
'''
1.drf在self.initial_request中重新封装了request对象,并向下兼容了django的request属性。
2.然后在self.initial中对request进行了用户、权限、吞吐量认证。
3.利用反射,执行我们自己的视图类对request请求进行处理。
4.在self.finalize_request中对response对象进行处理(如:渲染)
5.最终返回response对象
'''
请求解析模块
'''
1.二次封装了原生django的wsgi协议的request对象,并做了向下兼容(原来request对象的内容,用封装过的request也可以访问)
2.将所有拼接参数都放在request.query_params中,将所有数据包参数都放在request.data中
3.路由的又名无名分组的数据还是保存在args和kwargs
'''
REST_FRAMEWORK = {
# 解析类根据请求头中的 Content-Type
'DEFAULT_PARSER_CLASSES': [
# Content-Type: application/json
'rest_framework.parsers.JSONParser',
# Content-Type: application/x-www-form-urlencoded
'rest_framework.parsers.FormParser',
# Content-Type: multipart/form-data
'rest_framework.parsers.MultiPartParser'
],
}
响应渲染模块
'''
1.当三大认证模块和自己处理请求的视图函数类没有出现异常时--源码中我们可以看到if isinstance(response, Response):
2.响应的数据会交给渲染模块来完成数据的悬案,渲染方式有两种:Json格式数据渲染、Browser格式数据渲染
'''
REST_FRAMEWORK = {
# 响应渲染类
'DEFAULT_RENDERER_CLASSES': [
'rest_framework.renderers.JSONRenderer',
# 如果直接返回api.html会泄露源码 可对api.html进行修改或直接注释掉
'rest_framework.renderers.BrowsableAPIRenderer',
],
}
序列化组件
单表序列化
models.py
class User(models.Model):
SEX_CHOICES = ((0,'男'),(1,'女'))
name = models.CharField(max_length=64)
age = models.IntegerField()
height = models.DecimalField(max_digits=5,decimal_places=2,default=0)
sex = models.IntegerField(choices=SEX_CHOICES,default=0)
icon = models.ImageField(upload_to='icon',default='icon/default.png')
def __str__(self):
return self.name
class Meta:
verbose_name_plural = '用户表'
serializers.py
from rest_framework import serializers
from . import models
class UserModelSerializer(serializers.ModelSerializer):
# 是为哪一个model类定制的序列化类
class Meta:
model = models.User
# 设置参与序列化和反序列化的字段
'''
插拔式设计:
在model的类中提前制作好“插头”
外部选择性使用“插头”即可
'''
fields = ['name','age','height','sex','icon']
views.py
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import settings
from . import models
from . import serializers
class UserAPIView(APIView):
def get(self, request, *args, **kwargs):
pk = kwargs.get('pk')
try:
if pk:
obj = models.User.objects.get(pk=pk)
serializer = serializers.UserModelSerializer(obj, many=False)
print(serializer.data)
return Response(serializer.data)
else:
objs = models.User.objects.all()
serializer = serializers.UserModelSerializer(objs, many=True)
print(serializer.data)
return Response(serializer.data)
except:
return Response({'status': 1, 'msg': '请求数据不存在'})
def post(self, request, *args, **kwargs):
print(request.data)
return Response('post ok')
附:源码分析