一、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 解析器
原文地址:https://www.cnblogs.com/zane021/p/9669443.html