zoukankan      html  css  js  c++  java
  • 一、Django CBV and Django RestFramework

    一、Django CBV 调用流程

    r'^login/', views.LoginView.as_view()
    r'^login/', views.as_view()
    r'^login/', views.view()
    
    class View(object):
        http_method_names = ['get', 'post', 'put', 'patch', 'delete', 'head', 'options', 'trace']
    
        def view(request, *args, **kwargs):
            self = cls(**initkwargs)
            return self.dispatch(request, *args, **kwargs)
    
        def dispatch(self, request, *args, **kwargs):
            if request.method.lower() in self.http_method_names:
                handler = getattr(self, request.method.lower(), self.http_method_not_allowed)
            else:
                handler = self.http_method_not_allowed
            return handler(request, *args, **kwargs)
    
    from django.views import View
    
    class LoginView(View):
        def get(self, request):
            return render(request, 'login.html')
    
        def post(self, request):
            user = request.POST.get('user')
            pwd = request.POST.get('pwd')
            if user == 'zane' and pwd == '123':
                return HttpResponse('用户 %s 登陆成功!' % user)
            else:
                return HttpResponse('用户名或密码错误!')
    Django CBV调用流程

    二、Django RestFramework 调用流程

    r'^teachers/', views.TeacherView.as_view()
    r'^teachers/', APIView.as_view()
    r'^teachers/', View.view()
    
    class View(object):
        http_method_names = ['get', 'post', 'put', 'patch', 'delete', 'head', 'options', 'trace']
    
        def view(request, *args, **kwargs):
            self = cls(**initkwargs)
            # 此时返回的是 APIView.dispatch(request, *args, **kwargs)
            return self.dispatch(request, *args, **kwargs)
    
        def dispatch(self, request, *args, **kwargs):
            if request.method.lower() in self.http_method_names:
                handler = getattr(self, request.method.lower(), self.http_method_not_allowed)
            else:
                handler = self.http_method_not_allowed
            return handler(request, *args, **kwargs)
    
    class APIView(View):
        def as_view(cls, **initkwargs):
            view = super(APIView, cls).as_view(**initkwargs)
            return csrf_exempt(view)
    
        def dispatch(self, request, *args, **kwargs):
            if request.method.lower() in self.http_method_names:
                handler = getattr(self, request.method.lower(),
                                  self.http_method_not_allowed)
            else:
                handler = self.http_method_not_allowed
    
            response = handler(request, *args, **kwargs)
            return self.response
    
    from rest_framework.views import APIView
    from django.core.serializers import serialize
    
    class TeacherView(APIView):
        def get(self, request):
            teachers = Teacher.objects.all()
            teachers = serialize('json', teachers)
            return HttpResponse(teachers)
    
        def post(self, request):
            return HttpResponse('OK')
    Django RestFramework 调用流程

     三、Django 序列化

    r'^courses/', views.CourseView.as_view()
    
    from django.views import View
    
    class CourseView(View):
        def get(self, request):
            # 1. json 序列化
            # import json
            # courses = Course.objects.all()
            # tmp = []
            # for course in courses:
            #     tmp.append({"name": course.name})
            # courses = json.dumps(tmp, ensure_ascii=False)
    
            # 2. Django 自带序列化组件
            from django.core.serializers import serialize
            courses = Course.objects.all()
            courses = serialize('json', courses)
            return HttpResponse(courses)
    
        def post(self, request):
            return HttpResponse('ok')
    Django 序列化

    四、Django RestFramework 序列化

    r'^course_detail/', views.CourseDetailView.as_view()
    
    from rest_framework import serializers
    
    class CourseDetailSerializer(serializers.Serializer):
        # 一对一、一对多字段,使用 source 参数获取序列化字段
        course = serializers.CharField(source='course.name')
    
        # 多对多字段,使用 SerializerMethodField 并指定 get_teachers 方法获取序列化字段
        teachers = serializers.SerializerMethodField()
    
        def get_teachers(self, obj):
            tmp = []
            for o in obj.teachers.all():
                tmp.append(o.name)
            teachers = ','.join(tmp)
            return teachers
    
    from rest_framework.views import APIView
    from rest_framework.response import Response
    
    class CourseDetailView(APIView):
        def get(self, request):
            # Django Restframework 序列化
            course_details = CourseDetail.objects.all()
            course_detail_serializer_obj = CourseDetailSerializer(course_details, many=True)
            return Response(course_detail_serializer_obj.data)
    
        def post(self, request):
            return HttpResponse('ok')
    Django RestFramework Serializer 序列化
    from rest_framework import serializers
    from api.models import UserToken
    
    class UserTokenSerializer(serializers.ModelSerializer):
        # 覆盖并自定义序列化字段(一对一、一对多、多对多都可以覆盖自定义)
        user = serializers.CharField(source='user.user')
    
        class Meta:
            model = UserToken
            fields = '__all__'
    
    
    from rest_framework.views import APIView
    from api.serializers import UserTokenSerializer
    from rest_framework.response import Response
    
    class UserTokenView(APIView):
        def get(self, request):
            # Django Restframework 序列化
            user_tokens = UserToken.objects.all()
            user_token_serializer_obj = UserTokenSerializer(user_tokens, many=True)
            return Response(user_token_serializer_obj.data)
    
        def post(self, request):
            return HttpResponse('ok')
    Django RestFramework ModelSerializer 序列化

    五、Django Restframework 视图

    from rest_framework import serializers
    from api.models import UserToken
    
    class UserTokenSerializer(serializers.ModelSerializer):
        user = serializers.CharField(source='user.user')
        token = serializers.CharField()
    
        def create(self, validated_data):
            user = int(validated_data.get('user').get('user'))
            token = validated_data.get('token')
            user_obj = User.objects.get(pk=user)
            user_token_obj = UserToken.objects.create(user=user_obj, token=token)
            return user_token_obj
    
        class Meta:
            model = UserToken
            # fields = '__all__'
            exclude = ['id']
    
    
    from rest_framework.views import APIView
    from api.serializers import UserTokenSerializer
    from rest_framework.response import Response
    
    class UserTokenView(APIView):
        def get(self, request):
            # Django Restframework 序列化
            user_tokens = UserToken.objects.all()
            user_token_serializer_obj = UserTokenSerializer(user_tokens, many=True)
            return Response(user_token_serializer_obj.data)
    
        def post(self, request):
            ret = {
                'status': 200,
                'message': '创建UserToken成功!'
            }
            print(request.data)
            user_token_serializer_obj = UserTokenSerializer(data=request.data)
            if user_token_serializer_obj.is_valid():
                user_token_serializer_obj.save()
            else:
                ret['status'] = 2001
                ret['message'] = user_token_serializer_obj.errors
            return Response(ret)
    
    class UserTokenDetailView(APIView):
        def get(self, request, pk):
            user_token = UserToken.objects.filter(pk=pk).first()
            user_token_serializer_obj = UserTokenSerializer(user_token, many=False)
            return Response(user_token_serializer_obj.data)
    
        def put(self, request, pk):
            ret = {
                'status': 200,
                'message': '更新UserToken成功!'
            }
            user_token = UserToken.objects.filter(pk=pk).update(token=request.data.get('token'))
            if not user_token:
                ret['status'] = 2001
                ret['message'] = '更新UserToken失败!'
            return Response(ret)
    
        def delete(self, request, pk):
            ret = {
                'status': 200,
                'message': '删除UserToken成功!'
            }
            if not UserToken.objects.filter(pk=pk).delete():
                ret['status'] = 2002
                ret['message'] = '删除UserToken失败!'
            return Response(ret)
    Django Restframework 视图一 APIView类编写视图
    from rest_framework import serializers
    from api.models import User
    
    class UserSerializer(serializers.Serializer):
        user = serializers.CharField()
        type = serializers.CharField()
        bely = serializers.IntegerField()
    
        def create(self, validated_data):
            user_obj = User.objects.create(**validated_data)
            return user_obj
    
    # 方法1 使用 ListModelMixin, CreateModelMixin, RetrieveModelMixin, UpdateModelMixin, DestroyModelMixin, generics.GenericAPIView 类
    from rest_framework.mixins import ListModelMixin, CreateModelMixin
    from rest_framework.mixins import RetrieveModelMixin, UpdateModelMixin, DestroyModelMixin
    from rest_framework import generics
    
    class UserView(ListModelMixin, CreateModelMixin, generics.GenericAPIView):
        queryset = User.objects.all()
        serializer_class = UserSerializer
    
        def get(self, request, *args, **kwargs):
            return self.list(request, *args, **kwargs)
    
        def post(self, request, *args, **kwargs):
            return self.create(request, *args, **kwargs)
    
    
    class UserDetailView(RetrieveModelMixin, UpdateModelMixin, DestroyModelMixin, generics.GenericAPIView):
        queryset = User.objects.all()
        serializer_class = UserSerializer
    
        def get(self, request, *args, **kwargs):
            return self.retrieve(request, *args, **kwargs)
    
        def post(self, request, *args, **kwargs):
            return self.update(request, *args, **kwargs)
    
        def delete(self, request, *args, **kwargs):
            return self.destroy(request, *args, **kwargs)
    
    # 方法2 使用 ListCreateAPIView 和 RetrieveUpdateDestroyAPIView 类
    from rest_framework import generics
    
    class UserView(generics.ListCreateAPIView):
        queryset = User.objects.all()
        serializer_class = UserSerializer
    
    
    class UserDetailView(generics.RetrieveUpdateDestroyAPIView):
        queryset = User.objects.all()
        serializer_class = UserSerializer
    Django Restframework 视图二 mixin类编写视图
    # 路由配置
    r'^users/$', views.UserModelView.as_view({'get': 'list', 'post': 'create'})
    r'^users/(?P<pk>d+)/$', views.UserModelView.as_view({'get': 'retrieve', 'post': 'update'})
    
    # 序列化类
    from rest_framework import serializers
    from api.models import User
    
    class UserSerializer(serializers.Serializer):
        user = serializers.CharField()
        type = serializers.CharField()
        bely = serializers.IntegerField()
    
        def create(self, validated_data):
            user_obj = User.objects.create(**validated_data)
            return user_obj
    
    # 视图使用已经混合好的 ModelViewSet 类
    from rest_framework.viewsets import ModelViewSet
    
    class UserModelView(ModelViewSet):
        queryset = User.objects.all()
        serializer_class = UserSerializer
    Django Restframework 视图三 使用 mixed-in 类编写视图
    from django.shortcuts import get_object_or_404 as _get_object_or_404
    
    # 补充:第5步 调用get_object_or_404 方法,实际调用 django.shortcuts 导入的 get_object_or_404 方法
    def get_object_or_404(queryset, *filter_args, **filter_kwargs):
        return _get_object_or_404(queryset, *filter_args, **filter_kwargs)
    
    # 补充:第5步 实际的 django.shortcuts.get_object_or_404 被调用
    def get_object_or_404(klass, *args, **kwargs):
        return queryset.get(*args, **kwargs)
    
    class GenericAPIView(views.APIView):
        lookup_field = 'pk'
        lookup_url_kwarg = None
    
        def get_queryset(self):
            # 2. 获取视图类的 queryset 属性
            queryset = self.queryset
            if isinstance(queryset, QuerySet):
                queryset = queryset.all()
            return queryset
    
        def get_object(self):
            # 1. 获取并过滤视图类的 queryset 属性
            queryset = self.filter_queryset(self.get_queryset())
    
            # 3. 查询过滤键名
            lookup_url_kwarg = self.lookup_url_kwarg or self.lookup_field
            
            # 4. 过滤参数(定义成字典)
            filter_kwargs = {self.lookup_field: self.kwargs[lookup_url_kwarg]}
            
            # 5. 传入过滤参数进行过滤,调用上面的 get_object_or_404 方法
            obj = get_object_or_404(queryset, **filter_kwargs)
            return obj
    
    
    # 补充:第3步 self.kwargs 来自调用视图时传入的参数
    class ViewSetMixin(object):
        def as_view(cls, actions=None, **initkwargs):
            def view(request, *args, **kwargs):
                self.request = request
                self.args = args
                self.kwargs = kwargs
    Django Restframework 获取视图操作对象流程

    六、Django Restframework 解析器

    # Django Restframework 解析器调用流程
    # 1. 使用视图类单独配置
    from rest_framework.parsers import JSONParser, FormParser, MultiPartParser
    
    class UserModelView(ModelViewSet):
        parser_classes = [JSONParser, FormParser, MultiPartParser]
    
    # 2. 使用settings全局配置
    # settings 全局配置
    REST_FRAMEWORK = {
    'DEFAULT_PARSER_CLASSES': (
            'rest_framework.parsers.JSONParser',
            'rest_framework.parsers.FormParser',
            'rest_framework.parsers.MultiPartParser'
        )
    }
    
    # 3. 如果settings没有配置,则使用 api_settings 的默认配置
    DEFAULTS = {
        'DEFAULT_PARSER_CLASSES': (
            'rest_framework.parsers.JSONParser',
            'rest_framework.parsers.FormParser',
            'rest_framework.parsers.MultiPartParser'
        )
    }
    
    # 源码调用流程
    class APIView(View):
        # 视图类没有 self.parser_classes 属性时调用
        parser_classes = api_settings.DEFAULT_PARSER_CLASSES
    
        def get_parsers(self):
            # 1. 获取视图类单独配置
            return [parser() for parser in self.parser_classes]
    
        def initialize_request(self, request, *args, **kwargs):
            return Request(
                request,
                # 获取解析器
                parsers=self.get_parsers(),
                authenticators=self.get_authenticators(),
                negotiator=self.get_content_negotiator(),
                parser_context=parser_context
            )
    
        def dispatch(self, request, *args, **kwargs):
            # 从初始化request开始调用流程
            request = self.initialize_request(request, *args, **kwargs)
    
    
    # 当视图类没有 self.parser_classes 属性时调用
    api_settings = APISettings(None, DEFAULTS, IMPORT_STRINGS)
    
    class APISettings(object):
        # 获取 settings 全局配置
        @property
        def user_settings(self):
            if not hasattr(self, '_user_settings'):
                self._user_settings = getattr(settings, 'REST_FRAMEWORK', {})
            return self._user_settings
    
        def __getattr__(self, attr):
            try:
                # 2. 获取 settings 全局配置
                val = self.user_settings[attr]
            except KeyError:
                # 3. 获取 api_settings 默认配置
                val = self.defaults[attr]
            setattr(self, attr, val)
            return val
    Django Restframework 解析器
  • 相关阅读:
    jmeter的基本功能使用详解
    服务器资源监控插件(jmeter)
    前端技术之--CSS
    前端技术之--HTML
    TCP/IP基础知识
    TCP/IP、Http的区别
    关于性能调优
    如何修改Docker已运行实例的端口映射
    Mysql 主从同步配置
    Presto的基本概念
  • 原文地址:https://www.cnblogs.com/zane021/p/9669443.html
Copyright © 2011-2022 走看看