# 易忘点 #
1. update_or_create -- 如果有就更新,没有则创建
models.表名.objects.update_or_create(user=obj,defaults={‘要创建的字段‘:值})
2. restframework 常用的类
from rest_framework.views import APIView
from rest_framework.generics import GenericAPIView
from rest_framework.viewsets import GenericViewSet
from rest_framework.viewsets import ModelViewSet
from rest_framework.response import Response
3. models 中注册选择项
level_choices = (
(1,‘初级‘),
(2,‘中级‘),
(3,‘高级‘),
)
level = models.IntegerField(verbose_name=‘课程难易程度‘,choices=level_choices,default=1)
4. restframework 查询类
from rest_framework import serializers
## serializers.ModelSerializer -- 可直接调用 Meta 的方法
class CourseDetailSerializer(serializers.ModelSerializer):
# source -- 用于 OneToOne , ForeignKey , choice 查单独一项
title = serializers.CharField(source=‘course.title‘)
course_img = serializers.CharField(source=‘course.course_img‘)
level = serializers.CharField(source=‘course.get_level_display‘)
# 用于 ManyToMany 的多条查询
recommend = serializers.SerializerMethodField()
chapter = serializers.SerializerMethodField()
class Meta:
model = models.CourseDetail
fields = [‘course‘,‘title‘,‘course_img‘,‘level‘,‘slogon‘,‘why‘,‘recommend‘,‘chapter‘]
# 多条查询需要在上面的 recommend 前面加上 get_ -- > get_recommend(self,ojb)
def get_recommend(self,obj):
# 查询推荐课程 关联表 Course 对应的字段
queryset = obj.recommend_courses.all()
return [{‘id‘:row.id,‘title‘:row.title } for row in queryset]
# 反向查询 被 ForeignKey 关联的表
def get_chapter(self,obj):
queryset = obj.course.chapter_set.all()
return [{‘id‘:row.id,‘name‘:row.name} for row in queryset]
5. cookie 使用
from rest_framework.authentication import BaseAuthentication # 认证的模块
from rest_framework.exceptions import AuthenticationFailed # 抛异常的模块
from app01 import models
class Auth(BaseAuthentication):
"""
cookie 认证组件 用于返回当前访问用户是否是 真实拿着 cookie 值的用户
"""
def authenticate(self, request):
token = request.query_params.get(‘token‘)
obj = models.UserToken.objects.filter(token=token).first()
if not obj:
raise AuthenticationFailed({‘code‘:0,‘error‘:‘Coken认证失败‘})
return (obj.user.username,obj)
authentication_classes = [Auth,] # cookie 认证
6. 版本认证
01. url:
re_path(‘^api/(?P<version>[v1|v2]+)/‘,include(‘app01.urls‘))
re_path(‘^version/$‘,version.VersionView.as_view()),
02. views:
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.versioning import QueryParameterVersioning,URLPathVersioning
class VersionView(APIView): # 版本组件
versioning_class = QueryParameterVersioning
# 记得加 *args,**kwargs 否则 version 会无法获取
def get(self,request,*args,**kwargs):
# self.dispatch
print(request.version)
return Response(‘ok‘)
03. settings 配置
REST_FRAMEWORK = {
# 解析格式 -- JSON
‘DEFAULT_RENDERER_CLASSES‘:[‘rest_framework.renderers.JSONRenderer‘,‘rest_framework.renderers.BrowsableAPIRenderer‘,],
‘DEFAULT_VERSIONING_CLASS‘:‘rest_framework.versioning.QueryParameterVersioning‘, # 版本控制 的全局配置
‘ALLOWED_VERSIONS‘:[‘v1‘,‘v2‘], # 允许的版本
‘VERSION_PARAM‘:‘version‘, # 参数
‘DEFAULT_VERSION‘:‘v1‘, # 默认版本
}
7. 跨域
1. 中间件 注册 : ‘app01.cors.CORSMiddleware‘,
2. 封装方法
class MiddlewareMixin(object):
def __init__(self, get_response=None):
self.get_response = get_response
super(MiddlewareMixin, self).__init__()
def __call__(self, request):
response = None
if hasattr(self, ‘process_request‘):
response = self.process_request(request)
if not response:
response = self.get_response(request)
if hasattr(self, ‘process_response‘):
response = self.process_response(request, response)
return response
class CORSMiddleware(MiddlewareMixin):
def process_response(self,request,response):
# 添加响应头
# 允许你的域名来获取我的数据
response[‘Access-Control-Allow-Origin‘] = "*"
# 允许你携带Content-Type请求头
# response[‘Access-Control-Allow-Headers‘] = "Content-Type"
# 允许你发送DELETE,PUT
# response[‘Access-Control-Allow-Methods‘] = "DELETE,PUT"
# 预检请求 -- 登陆的跨域
if request.method == ‘OPTIONS‘:
response[‘Access-Control-Allow-Headers‘] = ‘Content-Type‘
# 需要什么类型的请求头就在后面直接添加,不能加*
response[‘Access-Control-Allow-Methods‘] = ‘PUT,DELETE‘
return response
原文:https://www.cnblogs.com/chaoqi/p/10446793.html