zoukankan      html  css  js  c++  java
  • [django]梳理drf知识点

    要实现的功能

    idc_list/
        get  列出所有
        post 创建一个idc
    
    idc_detail/1/
        get    获取一个idc
        put    修改一个idc
        delete 删除一个idc
    

    一般url是这样处理的

        url("^idcs/$", idc_list),
        url("^idcs/(?P<pk>[0-9]+)/$", idc_detail)
    

    从后端取数据到前端有哪些流程? 什么叫序列化? 什么叫反序列化?

    序列化&反序列化

    对象 -> 字符串 是序列化 json.dump()
    字符串->对象 是反序列化 json.parse()


    3件大事

    1.取数据

    2.序列化

    3.方法绑定 asview方法搞定

    GenericAPIView2个get冲突,必须写2个view,而viewset重写了as_view方法,解决了这个url问题

    - GenericAPIView不能把所有的都混在一起,必须分2个view写
    
    class IdcList_v4(generics.GenericAPIView, mixins.ListModelMixin, mixins.CreateModelMixin):
        queryset = Idc.objects.all()
        serializer_class = IdcSerializer
    
        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 IdcDetail_v4(generics.GenericAPIView, mixins.RetrieveModelMixin, mixins.UpdateModelMixin,
                       mixins.DestroyModelMixin):
        queryset = Idc.objects.all()
        serializer_class = IdcSerializer
    
        def get(self, request, *args, **kwargs):
            return self.retrieve(request, *args, **kwargs)
    
        def put(self, request, *args, **kwargs):
            return self.update(request, *args, **kwargs)
    
        def delete(self, request, *args, **kwargs):
            return self.destroy(request, *args, **kwargs)
    
    

    1个资源为什么要2个url? viewset可以解决idc_list和idc_detail 1个资源两个url问题

    - viewset可以这样写
    
    class IdcListViewset_v6(viewsets.GenericViewSet, mixins.ListModelMixin, mixins.CreateModelMixin,
                            mixins.RetrieveModelMixin, mixins.UpdateModelMixin,
                            mixins.DestroyModelMixin):
        queryset = Idc.objects.all()
        serializer_class = IdcSerializer
    
    

    巧妙的写2个绑定关系,都绑定到一个试图上

        path('idcs/', views.IdcListViewset.as_view({'get': 'list', 'post': 'create'}), name='idc_list'),
        path('idcs/<int:pk>/', views.IdcDetailViewset.as_view({'get': 'retrieve', 'put': 'update', 'delete': 'destroy'}),
    

    最终被router彻底解决

    rom rest_framework.routers import DefaultRouter
    from idcs.views import IdcViewset
    
    route = DefaultRouter()
    route.register('idcs', IdcViewset)
    
    
    urlpatterns = [
        path('', include(route.urls)),
    ]
    

    mixin做什么事情?

    1,取数据
    2.序列化 --这两项mixins.RetrieveModelMixin做的实行
    
    3.绑定方法:  as_view做点事情
    
    取数据    序列化    render                   方法绑定
    mixin    mixin     APIView+Response干了     as_view干了
                       存数据: IdcSerilizer(data=request.data)
                       取数据: Response(IdcSerilizer(idc.data))
    

    3种as_view

    • as_view的功能

    • as_view的内置3种

    1. as_view()  base  
    2. as_view()  restframework  重写了as_view方法
    3. as_view()  Viewset            重写了as_view方法
    
    - 用的的是 1. as_view()  base  
    class IdcList_v3(APIView):
        def get(self, request):
            return Response(IdcSerializer(Idc.objects.all().data, many=True))
    
        def post(self, request):
            serializer = IdcSerializer(data=request.data)
            if serializer.is_valid():
                serializer.save()
                return HttpResponse("创建成功")
            return HttpResponse("创建失败")
    
    - 用的是 2. as_view()  restframework
    class IdcList_v5(generics.GenericAPIView, mixins.ListModelMixin, mixins.CreateModelMixin):
        queryset = Idc.objects.all()
        serializer_class = IdcSerializer
    
        def get(self, request, *args, **kwargs):
            return self.list(request, *args, **kwargs)
    
        def post(self, request, *args, **kwargs):
            return self.create(request, *args, **kwargs)
    
    
    - 用的是 3. as_view()  Viewset(要求绑定关系写到url里)
    
    class IdcListViewset(viewsets.GenericViewSet, mixins.ListModelMixin, mixins.CreateModelMixin):
        queryset = Idc.objects.all()
        serializer_class = IdcSerializer
    
        path('idcs/', views.IdcListViewset.as_view({'get': 'list', 'post': 'create'}), name='idc_list'),
        path('idcs/<int:pk>/', views.IdcDetailViewset.as_view({'get': 'retrieve', 'put': 'update', 'delete': 'destroy'}),
             name='idc_detail'),
    

    提交数据,数据验证流程

    提交一次数据流程

    class ManufacturerSerializer(serializers.ModelSerializer):
        class Meta:
            model = Manufacturer
            fields = "__all__"
    
        def to_internal_value(self, data):
            print('to_internal_value(data): ', data)
            return super(ManufacturerSerializer, self).to_internal_value(data)
    
        def validate_vender_name(self, data):
            print('validate_vender_name(data): ', data)
            return data
    
        def validate(self, attrs):
            print("validate验证(attrs): ", attrs)
            return attrs
    
        def create(self, validated_data):
            print('create(validated_data): ', validated_data)
            return Manufacturer.objects.create(**validated_data)
    
    to_internal_value(data)     : <QueryDict: {'csrfmiddlewaretoken': ['bp0QXpil9GwXUDhKYO0ut03dr2C6YGVT12WWOGIV49z7QMEeZHRE5Qsz4DBE5tTt'], 'vender_name': ['dell'], 'tel': ['13111111111'], 'mail': ['xxx@foxmail.com'], 'remark': ['test']}>
    validate_vender_name(data)  :  dell
    validate验证(attrs)         :  OrderedDict([('vender_name', 'dell'), ('tel', '13111111111'), ('mail', 'xxx@foxmail.com'), ('remark', 'test')])
    create(validated_data)      :  {'vender_name': 'dell', 'tel': '13111111111', 'mail': 'xxx@foxmail.com', 'remark': 'test'}
    

    子表展示主表的字段(to_representation): 希望获取某个机柜时候,展示idc的id&name

    注意: 从db取出数据到前端展示, 不经过validate和validate_data, 所以只能在to_representation处做.

    - IDC APP
    class Idc(models.Model):
        name = models.CharField(max_length=20)
        address = models.CharField(max_length=20)
        phone = models.CharField(max_length=20)
        letter = models.CharField(max_length=20)
    
        def __str__(self):
            return self.name
    
    
    - 机柜APP
    
    from idcs.models import Idc
    
    class Cabinet(models.Model):
        "机柜模型"
        idc = models.ForeignKey(Idc, on_delete=models.CASCADE)
        name = models.CharField('机柜名称', max_length=40)
    
        def __str__(self):
            return self.name
    
    

    默认是这样的, 看不出idc的名字

    - 机柜序列化类to_representation,抛给前端最后一步来动刀
    
    class CabinetSerializer(serializers.Serializer):
        "机柜序列化类"
        idc = serializers.PrimaryKeyRelatedField(many=False, queryset=Idc.objects.all())
        name = serializers.CharField(max_length=20)
    
        def create(self, validated_data):
            return Cabinet.objects.create(**validated_data)
    
        # instance是一个机柜的obj
        def to_representation(self, instance):
            print(instance)
            print(type(instance))     # <class 'cabinet.models.Cabinet'>
            print(instance.idc)
            print(type(instance.idc)) # <class 'idcs.models.Idc'>
            res = super(CabinetSerializer, self).to_representation(instance)
            print(res) # OrderedDict([('idc', 1), ('name', '1-2')])
            res['idc'] = {
                'name': instance.idc.name,
                'phone': instance.idc.phone
            }
            return res
    

    最接近前端的to_representation/to_internal_value处理后的OrderedDict可以k['v']形式取值

    也可以通过点的方式取

    OrderedDict([('idc', 1), ('name', '1-2')])
    
    
            res = super(CabinetSerializer, self).to_representation(instance)
            print(res) # OrderedDict([('idc', 1), ('name', '1-2')])
            res['idc'] = {
                'name': instance.idc.name,
                'phone': instance.idc.phone
            }
    

    制造商名称大写: 入库时4个节点可以修改

    validate时修改方便点.

    • to_internal_value时修改
    class ManufacturerSerializer(serializers.ModelSerializer):
        class Meta:
            model = Manufacturer
            fields = "__all__"
    
        def to_internal_value(self, data):
            print('data: ', data)
            res = super(ManufacturerSerializer, self).to_internal_value(data)
            print('res: ', res)
            res['vendor_name'] = res['vendor_name'].upper()
            return res
    
    
    
    data:  <QueryDict: {'csrfmiddlewaretoken': ['B27kAKtSmrRDmIUco8umj5nFbsdcnOOWVdlBRJ7DgRfJjnmSh7YINSk5nXNbYmoD'], 'vendor_name': ['cs7'], 'tel': ['13333333333'], 'mail': ['ihorse@foxmail.com'], 'remark': ['cs7']}>
    res:  OrderedDict([('vendor_name', 'cs7'), ('tel', '13333333333'), ('mail', 'ihorse@foxmail.com'), ('remark', 'cs7')])
    
    • validate_vendor_name时修改
    class ManufacturerSerializer(serializers.ModelSerializer):
        class Meta:
            model = Manufacturer
            fields = "__all__"
    
        def validate_vendor_name(self, value):
            print('value: ',value)
            return value.upper()
    
    cs6
    
    • validate时修改
    class ManufacturerSerializer(serializers.ModelSerializer):
        class Meta:
            model = Manufacturer
            fields = "__all__"
    
    
        def validate(self, attrs):
            print('validate(attrs): ', attrs)
            attrs['vendor_name'] = attrs['vendor_name'].upper()
            return attrs
    
    
    validate(attrs):  OrderedDict([('vendor_name', 'cs4'), ('tel', '13444444444'), ('mail', 'ihorse@foxmail.com'), ('remark', 'cs4')])
    
    • create时候修改
    class ManufacturerSerializer(serializers.ModelSerializer):
        class Meta:
            model = Manufacturer
            fields = "__all__"
    
        def create(self, validated_data):
            print('create(validated_data): ',validated_data)
            validated_data['vender_name'] = validated_data['vender_name'].upper()
            return Manufacturer.objects.create(**validated_data)
    
    create(validated_data):  {'vender_name': 'cs8', 'tel': '13444444444', 'mail': 'ihorse@foxmail.com', 'remark': None}
    

    本来想在创建型号时候指定制造商, 如果制造商不存在,则创建.如果存在则关联

    {
        "model_name": "mi8",
        "vender": "xiaomi"
    }
    
    
    class ProductModelSerializer(serializers.ModelSerializer):
        class Meta:
            model = ProductModel
            fields = "__all__"
    
        def to_internal_value(self, data):
            print(data)
            res = super(ProductModelSerializer, self).to_representation(data)
            print(2)
            try:
                manufacturer_obj = Manufacturer.objects.get(vender_name__exact=data['vender'])
            except Manufacturer.DoesNotExist:
                manufacturer_obj = Manufacturer.objects.create(vender_name=data['vender'])
            res['vender'] = manufacturer_obj
            return res
    
        # def validate_vender(self, value): #根本都走不到这里.在to_internal_value时字段serializer时候就报错了.
        #     "制造商验证"
        #     print('value: ', value, type(value))
        #     try:
        #         return Manufacturer.objects.get(vender_name__exact=value)
        #     except Manufacturer.DoesNotExist:
        #         print(type(value))
        #         return Manufacturer.objects.create(vender_name=value)
    
        # def validate(self, attrs):
        #     "主表验证子表唯一性"
        #     manufacturer_obj = attrs['vender']
        #     try:
        #         manufacturer_obj.productmodel_set(model_name__exact=attrs['model_name'])
        #     except ProductModel.DoesNotExist:
        #         return attrs
    
    <QueryDict: {'csrfmiddlewaretoken': ['afVAElHU9XdiA4J41r8Kiycs2uLqRwy9kyTK1tpyIuaNw5P6bg3yFf03fSmS3vwJ'], 'model_name': ['R710'], 'vender': ['1']}>
    
    • 下面这种写法也报错

    class ProductModelSerializer(serializers.ModelSerializer):
        class Meta:
            model = ProductModel
            fields = "__all__"
    
        def validate_manufacturer(self, value):
            "制造商唯一性验证"
            try:
                return Manufacturer.objects.get(vendor_name__exact=value)
            except Manufacturer.DoesNotExist:
                return self.create_manufacturer(value)
    
        def create_manufacturer(self, vendor_name):
            "创建制造商"
            return Manufacturer.objects.create(vendor_name=vendor_name)
    
        def validate(self, attrs):
            "制造商下型号唯一性验证"
            manufacturer_obj = attrs["manufacturer"]
            try:
                # 如果存在则获取索引
                # 如果不存在则创建并获取索引
                attrs["model_name"] = manufacturer_obj.productmodel_set.get(model_name__exact=attrs["model_name"])
            except ProductModel.DoesNotExist:
                attrs["model_name"] = self.create_product_model(manufacturer_obj, attrs["model_name"])
            return attrs
    

    解决这个问题

    1.序列化时外键是字符串
    2.和primarykey形成对比

    class ManufacturerSerializer(serializers.ModelSerializer):
        class Meta:
            model = Manufacturer
            fields = "__all__"
    
    
    class ProductModelSerializer(serializers.Serializer):
        # class Meta:
        #     model = ProductModel
        #     fields = "__all__"
        model_name = serializers.CharField(required=True)
        vender = serializers.CharField(required=True)
    
        def validate_vender(self, value):
            print(value)
            "制造商唯一性验证"
            try:
                return Manufacturer.objects.get(vender_name__exact=value)
            except Manufacturer.DoesNotExist:
                return self.create_manufacturer(value)
    
        def create_manufacturer(self, vender_name):
            "创建制造商"
            return Manufacturer.objects.create(vender_name=vender_name)
    
        def validate(self, attrs):
            "制造商下型号唯一性验证"
            print(attrs)
            manufacturer_obj = attrs["vender"]
            try:
                # 如果存在则获取索引
                # 如果不存在则创建并获取索引
                attrs["model_name"] = manufacturer_obj.productmodel_set.get(model_name__exact=attrs["model_name"])
            except ProductModel.DoesNotExist:
                # attrs["model_name"] = self.create_product_model(manufacturer_obj, attrs["model_name"])
                pass
            return attrs
    
        def create(self, validated_data):
            print(validated_data) # {'model_name': 'mi10', 'vender': <Manufacturer: xiaomi>}
            "创建型号"
            return ProductModel.objects.create(**validated_data)
    
    

    子表显示外键

    方法1: 继承ModelSerializer

    class ManufacturerSerializer(serializers.ModelSerializer):
        class Meta:
            model = Manufacturer
            fields = "__all__"
    
        def validate_vender_name(self, data):
            return data.upper()
    
    
    class ProductModelSerializer(serializers.ModelSerializer):
    
        class Meta:
            model = Manufacturer
            fields = "__all__"
    

    方法2: PrimaryKeyRelatedField

    class ManufacturerSerializer(serializers.ModelSerializer):
        class Meta:
            model = Manufacturer
            fields = "__all__"
    
        def validate_vender_name(self, data):
            return data.upper()
    
    
    class ProductModelSerializer(serializers.Serializer):  # 必须实现create: `create()` must be implemented.
        model_name = serializers.CharField(max_length=20)
        vender = serializers.PrimaryKeyRelatedField(many=False, queryset=Manufacturer.objects.all())
    
        def create(self, validated_data):
            ProductModel.objects.create(**validated_data)
    
    

    方法3:

    class ManufacturerSerializer(serializers.ModelSerializer):
        class Meta:
            model = Manufacturer
            fields = "__all__"
    
        def validate_vender_name(self, data):
            return data.upper()
    

    1.判断制造商是否存在: to_internal_value节点实现

    class ProductModelSerializer(serializers.Serializer):  # 必须实现create: `create()` must be implemented.
        model_name = serializers.CharField(max_length=20)
        vender = serializers.CharField(max_length=20)
    
        def to_internal_value(self, data):
            print(data)
            res = super(ProductModelSerializer, self).to_internal_value(data)
            print(res) # OrderedDict([('model_name', 'mi10'), ('vender', 'xiaomi')])
            try:
                res['vender'] = Manufacturer.objects.get(vender_name__exact=res['vender'])
            except Manufacturer.DoesNotExist:
                res['vender'] = Manufacturer.objects.create(vender_name=res['vender'])
            print(res) # OrderedDict([('model_name', 'mi10'), ('vender', <Manufacturer: xiaomi>)])
            return res
    
        def validate(self, attrs):
            print(attrs) # OrderedDict([('model_name', 'mi10'), ('vender', <Manufacturer: xiaomi>)])
            return attrs
    
        def create(self, validated_data):
            return ProductModel.objects.create(**validated_data)
    

    2.判断制造商是否存在: validate_vender节点实现

    class ProductModelSerializer(serializers.Serializer):  # 必须实现create: `create()` must be implemented.
        model_name = serializers.CharField(max_length=20)
        vender = serializers.CharField(max_length=20)
    
        def validate_vender(self, value):
            print(value)  # 'xiaomi'
            try:
                manufacturer_obj = Manufacturer.objects.get(vender_name__exact=value)
            except Manufacturer.DoesNotExist:
                manufacturer_obj = Manufacturer.objects.create(vender_name=value)
            return manufacturer_obj  # 相当于把manufacturer_obj赋给了vender
    
        def validate(self, attrs):
            print(attrs)  # OrderedDict([('model_name', 'mi11'), ('vender', <Manufacturer: xiaomi>)])
            return attrs
    
        def create(self, validated_data):
            return ProductModel.objects.create(**validated_data)
    

    3.判断制造商是否存在: validate节点实现

    class ProductModelSerializer(serializers.Serializer):  # 必须实现create: `create()` must be implemented.
        model_name = serializers.CharField(max_length=20)
        vender = serializers.CharField(max_length=20)
    
        def validate(self, attrs):
            print(attrs)  # OrderedDict([('model_name', 'p1'), ('vender', 'google')])
            try:
                attrs['vender'] = Manufacturer.objects.get(vender_name__exact=attrs['vender'])
            except Manufacturer.DoesNotExist:
                attrs['vender'] = Manufacturer.objects.create(vender_name=attrs['vender'])
            print(attrs)  # OrderedDict([('model_name', 'p1'), ('vender', <Manufacturer: google>)])
            return attrs
    
        def create(self, validated_data):
            return ProductModel.objects.create(**validated_data)
    
    

    方法4: 也可以在create时候实现

    通过主表,验证子表字段的唯一性: 验证该型号已存在

    方法1: 在to_internal验证

    方法2: 在valida_filed验证

    方法3: 在validate时候验证

    class ProductModelSerializer(serializers.Serializer):  # 必须实现create: `create()` must be implemented.
        model_name = serializers.CharField(max_length=20)
        vender = serializers.CharField(max_length=20)
    
        def validate(self, attrs):
            "制造商验证"
            print(attrs)  # OrderedDict([('model_name', 'p2'), ('vender', 'google')])
            try:
                attrs['vender'] = Manufacturer.objects.get(vender_name__exact=attrs['vender'])
            except Manufacturer.DoesNotExist:
                attrs['vender'] = Manufacturer.objects.create(vender_name=attrs['vender'])
            print(attrs)  # OrderedDict([('model_name', 'p2'), ('vender', <Manufacturer: google>)])
    
            "制造商下型号唯一性验证"
            try:
                attrs['vender'].productmodel_set.get(model_name__exact=attrs['model_name'])
                raise serializers.ValidationError("该型号已存在")
            except ProductModel.DoesNotExist:
                pass
            return attrs
    
        def create(self, validated_data):
            print(validated_data)  # OrderedDict([('model_name', 'p2'), ('vender', <Manufacturer: google>)])
            return ProductModel.objects.create(**validated_data)
    
    

    方法4: 在create时候验证

    class ProductModelSerializer(serializers.Serializer):  # 必须实现create: `create()` must be implemented.
        model_name = serializers.CharField(max_length=20)
        vender = serializers.CharField(max_length=20)
    
        def validate(self, attrs):
            "制造商验证"
            print(attrs)  # OrderedDict([('model_name', 'p2'), ('vender', 'google')])
            try:
                attrs['vender'] = Manufacturer.objects.get(vender_name__exact=attrs['vender'])
            except Manufacturer.DoesNotExist:
                attrs['vender'] = Manufacturer.objects.create(vender_name=attrs['vender'])
            print(attrs)  # OrderedDict([('model_name', 'p2'), ('vender', <Manufacturer: google>)])
    
            return attrs
    
        def create(self, validated_data):
            print(validated_data)  # OrderedDict([('model_name', 'p2'), ('vender', <Manufacturer: google>)])
            "制造商下型号唯一性验证"
            try:
                validated_data['vender'].productmodel_set.get(model_name__exact=validated_data['model_name'])
                raise serializers.ValidationError("该型号已存在")
            except ProductModel.DoesNotExist:
                return ProductModel.objects.create(**validated_data)
    
    

    继承逻辑关系图

    drf的版本迭代

    from django.http import HttpResponse, JsonResponse
    from django.shortcuts import render
    
    # Create your views here.
    from django.views.generic.base import View
    
    from rest_framework.decorators import api_view
    from rest_framework.response import Response
    from rest_framework.reverse import reverse
    from rest_framework.views import APIView
    from rest_framework import viewsets
    
    from .models import Idc
    from .serializers import IdcSerializer
    from rest_framework.renderers import JSONRenderer
    from rest_framework.parsers import JSONParser
    
    from rest_framework import mixins, generics
    
    
    class IdcView(viewsets.ModelViewSet):
        queryset = Idc.objects.all()
        serializer_class = IdcSerializer
    
    
    class IdcView_v7(viewsets.GenericViewSet,
                  mixins.ListModelMixin,
                  mixins.CreateModelMixin,
                  mixins.RetrieveModelMixin,
                  mixins.UpdateModelMixin,
                  mixins.DestroyModelMixin):
        queryset = Idc.objects.all()
        serializer_class = IdcSerializer
    
    
    
    class IdcView_v6(generics.ListCreateAPIView, generics.RetrieveUpdateDestroyAPIView):
        queryset = Idc.objects.all()
        serializer_class = IdcSerializer
    
    
    class IdcViewDetail_v6(generics.RetrieveUpdateDestroyAPIView):
        queryset = Idc.objects.all()
        serializer_class = IdcSerializer
    
    
    class IdcView_v5(generics.GenericAPIView, mixins.ListModelMixin, mixins.CreateModelMixin):
        queryset = Idc.objects.all()
        serializer_class = IdcSerializer
    
        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 IdcViewDetail_v5(generics.GenericAPIView,
                           mixins.RetrieveModelMixin,
                           mixins.UpdateModelMixin,
                           mixins.DestroyModelMixin):
        queryset = Idc.objects.all()
        serializer_class = IdcSerializer
    
        def get(self, request, *args, **kwargs):
            return self.retrieve(request, *args, **kwargs)
    
        def put(self, request, *args, **kwargs):
            return self.update(request, *args, **kwargs)
    
        def delete(self, request, *args, **kwargs):
            return self.destroy(request, *args, **kwargs)
    
    
    class IdcView_v4(APIView):
        def get(self, request, *args, **kwargs):
            return Response(IdcSerializer(Idc.objects.all(), many=True).data)
    
        def post(self, request, *args, **kwargs):
            serializer = IdcSerializer(data=request.data)
            if serializer.is_valid():
                serializer.save()
                return HttpResponse('添加成功')
            return HttpResponse('验证失败')
    
    
    class IdcViewDetail_v4(APIView):
        def get_object(self, pk):
            try:
                return Idc.objects.get(pk=pk)
            except Exception as e:
                return HttpResponse("无此记录")
    
        def get(self, request, pk, *args, **kwargs):
            return Response(IdcSerializer(self.get_object(pk)).data)
    
        def put(self, request, pk, *args, **kwargs):
            serializer = IdcSerializer(self.get_object(pk), data=request.data)
            if serializer.is_valid():
                serializer.save()
                return HttpResponse('添加成功')
            return HttpResponse('验证失败')
    
        def delete(self, request, pk, *args, **kwargs):
            self.get_object(pk).delete()
            return HttpResponse('删除成功')
    
    
    @api_view(['GET'])
    def api_root(request, format=None, *args, **kwargs):
        return Response(
            {
                'idc-list': reverse('idcs:idc-list', request=request)
            })
    
    
    @api_view(['GET', 'POST'])
    def idc_list_v3(request):
        if request.method == "GET":
            return Response(IdcSerializer(Idc.objects.all(), many=True).data)
        elif request.method == "POST":
            serializer = IdcSerializer(data=request.data)
            if serializer.is_valid():
                serializer.save()
                return HttpResponse('添加成功')
            return HttpResponse('验证失败')
    
    
    @api_view(['GET', 'PUT', 'DELETE'])
    def idc_detail_v3(request, pk):
        try:
            idc = Idc.objects.get(pk=pk)
        except Exception as e:
            return "记录不存在"
        if request.method == "GET":
            return Response(IdcSerializer(idc).data)
        if request.method == "PUT":
            serializer = IdcSerializer(idc, data=request.data)
            if serializer.is_valid():
                serializer.save()
                return HttpResponse('修改成功')
            return HttpResponse('验证失败')
        if request.method == "DELETE":
            idc.delete()
            return HttpResponse('删除成功')
    
    
    class IdcView_v2(View):
        def get(self, request):
            return HttpResponse(JSONRenderer().render(IdcSerializer(Idc.objects.all(), many=True).data))
    
        def post(self, request):
            serializer = IdcSerializer(data=request.data)
            if serializer.is_valid():
                serializer.save()
                return HttpResponse('添加成功')
            return HttpResponse('验证失败')
    
    
    class IdcViewDetail_v2(View):
        def get_object(self, pk):
            try:
                return Idc.objects.get(pk=pk)
            except Exception as e:
                return HttpResponse("无此记录")
    
        def get(self, request, pk):
            return HttpResponse(JSONRenderer().render(IdcSerializer(self.get_object(pk))))
    
        def put(self, request, pk):
            idc = self.get_object(pk)
            serializer = IdcSerializer(idc, data=JSONParser().parse(request))
            if serializer.is_valid():
                serializer.save()
                return HttpResponse('修改成功')
            return HttpResponse('验证失败')
    
    
    def idc_list_v1(request):
        if request.method == "GET":
            return HttpResponse(JSONRenderer().render(IdcSerializer(Idc.objects.all(), many=True).data))
        elif request.method == "POST":
            serializer = IdcSerializer(data=JSONParser().parse(request))
            if serializer.is_valid():
                serializer.save()
                return HttpResponse('添加成功')
            return HttpResponse('验证失败')
    
    
    def idc_detail_v1(request, pk):
        try:
            idc = Idc.objects.get(pk=pk)
        except Exception as e:
            return HttpResponse("没有这个记录")
    
        if request.method == "GET":
            return HttpResponse(JSONRenderer().render(IdcSerializer(idc).data))
        elif request.method == "PUT":
            serializer = IdcSerializer(idc, data=JSONParser().parse(request))
            if serializer.is_valid():
                serializer.save()
                return HttpResponse('更新成功')
            return HttpResponse('验证失败')
        elif request.method == "DELETE":
            Idc.objects.get(pk=pk).delete()
            return HttpResponse('删除成功')
    # @api_view(['GET', 'PUT'])
    # def idc_list(request, *args, **kwargs):
    #     if request.method == "GET":
    #         queryset = Idc.objects.all()
    #         serializer = IdcSerializer(queryset, many=True)
    #         return Response(serializer.data)
    #     elif request.method == "PUT":
    #         serializer = IdcSerializer(request.data)
    #         return HttpResponse("")
    
    

    urls.py

    from django.contrib import admin
    from django.urls import path, include
    from django.views.generic import TemplateView
    from rest_framework.routers import DefaultRouter
    from rest_framework.urlpatterns import format_suffix_patterns
    
    from idcs import views
    
    # idc_list = views.IdcView.as_view({
    #     'get': 'list',
    #     'post': 'create'
    # })
    #
    # idc_detail = views.IdcView.as_view({
    #     'get': 'retrieve',
    #     'put': 'update',
    #     'delete': 'destroy'
    # })
    
    route = DefaultRouter()
    route.register('idcs', views.IdcView)
    
    app_name = 'idcs'
    urlpatterns = [
        # path('', views.api_root),
        # path('idcs', idc_list, name='idc-list'),
        path('', include(route.urls)),
        # path('idcs/<int:pk>/', idc_detail, name='idc-detail'),
    ]
    # urlpatterns = format_suffix_patterns(urlpatterns)
    
    

    drf版本迭代总结

    理解序列化和反序列化的本质
    https://www.bilibili.com/video/av39886713?from=search&seid=17895786208711765947

    python使用protobuf序列化数据:
    https://blog.csdn.net/menghaocheng/article/details/80176763

    序列化: 后端->前端
    queryset -> serializer -> JSONRender -> 返回前端
    
    反序列化:后端<-前端
    queryset <- serializer <- JSONParse  <- 前端提交
    
    
    ApiView:
        Response,不用JSONRender/JSONParser了
        有界面了
    
    API_ROOT设置
    url设置
    
    IdcView_v4(APIView)
    IdcViewDetail_v4(APIView)
    
    
    IdcView_v5(generics.GenericAPIView, mixins.ListModelMixin, mixins.CreateModelMixin)
    IdcViewDetail_v5(generics.GenericAPIView,
                           mixins.RetrieveModelMixin,
                           mixins.UpdateModelMixin,
                           mixins.DestroyModelMixin):
        不需要关心数据了, 只需绑定方法
    
    
    IdcView_v6(generics.ListCreateAPIView, generics.RetrieveUpdateDestroyAPIView)
    IdcViewDetail_v6(generics.RetrieveUpdateDestroyAPIView)
        不需要关心数据,不需要绑定方法,但还是有2个视图+2个url
    
    
    IdcView_v7(viewsets.GenericViewSet,
                  mixins.ListModelMixin,
                  mixins.CreateModelMixin,
                  mixins.RetrieveModelMixin,
                  mixins.UpdateModelMixin,
                  mixins.DestroyModelMixin)
        不需要关心数据,需要绑定url, 有1个视图了.
    
    
    IdcView(viewsets.ModelViewSet)
        简化了写法.
    
                                        generics.ListCreateAPIView=generics.GenericAPIView+
                                                                   mixins.ListModelMixin+
                                                                   mixins.CreateModelMixin
    
    viewsets.ModelViewSet -> viewsets.GenericViewSet -->  generics.GenericAPIView(viewset再此基础上又封装了2层)
                             mixins.ListModelMixin
    

    route.register函数的base_name参数定制url(默认是modelname为准)

    譬如我写了2个viewset,针对的是相同的model和serializer

    class ServerAutoReportViewset(viewsets.ReadOnlyModelViewSet):
        queryset = Server.objects.all()
        serializer_class = ServerSerializer
    
    
    class ServerViewset(viewsets.ReadOnlyModelViewSet):
        queryset = Server.objects.all()
        serializer_class = ServerSerializer
    

    默认展示的时候以model名字来展示

    否则2个viewset只显示第一个.

    route.register('ServerAutoReport', ServerAutoReportViewset, base_name='ServerAutoReport')
    route.register('Server', ServerViewset, base_name='Server')
    

    drf继承图

  • 相关阅读:
    java基础面试题(一)
    关于Redis的十个高频面试问题
    postgres中的merge join
    cgdb调试postgresql
    再见了,程序员!
    掌握这个小技巧,让你的 C++ 编译速度提升 50 倍!
    C语言修仙大法!基础知识全复习(纯干货)!!!
    一锅端了!北京朝阳一互联网公司被端,警方上门,23人被带走…
    C++入口不是main?知乎上都快打起来了,你们不要再打了啦!
    不用创建项目,直接在 VS 里快速测试 C/C++ 代码 !
  • 原文地址:https://www.cnblogs.com/iiiiiher/p/9892809.html
Copyright © 2011-2022 走看看