易忘点

#  易忘点  #

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



猜你喜欢

转载自www.cnblogs.com/chaoqi/p/10446793.html