zoukankan      html  css  js  c++  java
  • Django1.0和2.0中的rest_framework的序列化组件之超链接字段的处理

    大家看到这个标题是不是有点懵逼,其实我就是想要一个这样的效果

    比如我get一条书籍的数据,在一对多的字段中我们显示一个url,看起来是不是很绚!

     下面我们就来实现这么一个东西

    首先我们一对多字段中的一表是 出版社表,因为我们这里要显示某个出版社的url,所以我们首先必须要为出版社的设计一个url

    """
    from django.conf.urls import url
    from django.contrib import admin
    from django.conf.urls import include
    from app1 import views
    urlpatterns = [
        url(r'^test/', views.test),
        url(r'^test_cbv/', views.test_cbv.as_view(),name="test1"),
        url(r'^test_rest/', views.Rest_view.as_view(),name="test2"),
        url(r'^book_cbv/', views.Book_cbv.as_view(),name="test3"),
        url(r'^publish_detail_cbv/(?P<id>d+)', views.Pub_detail_cbv.as_view(),name="publish_url_name"),
        url(r'^book_detail_cbv/(?P<id>d+)', views.Book_detail_cbv.as_view(),name="test4"),
    ]
    

      

    就是这样的一条

     然后我们为出版社设计modelserializer类,所有的字段都使用默认的形式

    class pubmodelserializer(serializers.ModelSerializer):
        class Meta:
            model = models.Publish
            fields = "__all__"
    

      

    然后我们写cbv中的c,也就是视图类

    class Pub_detail_cbv(APIView):
        def get(self,request,id):
            obj = models.Publish.objects.filter(id=id).first()
    
            # bs = pubmodelserializer(obj,many=False,context={'request': request})
            bs = pubmodelserializer(obj, many=False)
            return Response(bs.data)
    
        def put(self,request,id):
            obj = models.Publish.objects.filter(id=id)
            bs = pubmodelserializer(obj,data=request.data)
            if bs.is_valid():
                bs.save()
    
                return Response(bs.data)
            else:
                return Response(bs.errors)
    

    这样,基本框架就完成了,我们开始来实现超链接

    首先要为每条url设计别名

    因为我们要对书籍表中的某个字段做超链接处理,所以需要到书籍表的modelserializer类中为超链接字段做特殊的处理

    超链接字段使用使用HyperLinkedIdentityField这个类

     这个必须要有3个参数,后面会具体的分析

    class bookmodelserializer(serializers.ModelSerializer):
        class Meta:
            model = models.Book
            fields = "__all__"
    
        book_publish = serializers.HyperlinkedIdentityField(
            view_name="publish_url_name",
            lookup_field="book_publish_id",
            lookup_url_kwarg="id"
    
        )
    

      

    就是我截图框红的这里,下面我们来具体解释下

    view_name就是这个字段我们想显示的url的别名

    lookup_field字段是一个我们自定义的值,因为我们这里的类是对model对象做序列化处理,所以每个model对象都一个序列化的实例,而这个字段就是这个实例的出版社的id

    lookup_url_kwarg字段就是我们的url参数,比如我们这里写的是id,那么lookup_filed这个参数对应的值就会赋值给url中命名变量为id这个变量

    这里我们在看下url,因为我们的url中这里要显示的id,所以我们在lookup_fileld就要获取对应的出版社的id,所以这里大家是否清楚了,lookup_fileld要获取什么值,完全取决于我们在url中变量想要什么值;这里为什么还要指定url中的变量的名称呢?因为url中的变量可不止一个,所以必须要指定变量的名称;这里不能使用位置参数,必须使用命名参数

     下面我们通过postman发送一个get请求测试一下

    发现会报错

     这个报错要这样解决

    在视图类中序列化一个modelserializer对象的时候要这么写,其实这也是一个固定的写法,在所以实例化model对象或者queryset中均这样写就好了

    class Book_detail_cbv(APIView):
        def get(self,request,id):
            obj = models.Book.objects.filter(id=id).first()
    
            bs = bookmodelserializer(obj,many=False,context={'request': request})
            # bs = bookmodelserializer(obj, many=False,)
            return Response(bs.data)
    

      

     然后我们在测试一下

    上面是django1.0版本的处理

      

    ===============================================================================================================

     在djaong2.0中,稍微有一点不同,就是django2.0中对于二级路由的命令别名和django1.0有些改动,这里稍微做一下回忆

    首先在工程的url文件中需要按照下面的格式来写

     然后在对应app的url中要这么写

     最后在超链接类中view_name要这样指定url的别名

     其他均和在django1.0中保持一致

    附上在django2.0中的所有的代码

    序列化处理的代码

    from rest_framework import serializers
    from app1 import models
    from rest_framework.views import APIView
    from rest_framework.response import Response
    from django.urls import reverse
    class bookmodelserializers(serializers.ModelSerializer):
        class Meta:
            model = models.Book
            fields = "__all__"
        #
        # book_publish = serializers.CharField(source="book_publish.publish_name")
        book_publish = serializers.HyperlinkedIdentityField(
            view_name= "app1:pub_detail",
            lookup_field="book_publish_id",
            lookup_url_kwarg="pid"
        )
     
     
        def create(self, validated_data):
            print("validated_data",validated_data,"==============================")
     
     
    class pubmodelserializers(serializers.ModelSerializer):
        class Meta:
            model = models.Publish
            fields = "__all__"
    

      

    视图类的代码

    from django.shortcuts import render
    from django.shortcuts import HttpResponse
    from django.shortcuts import redirect
    from django import views
     
    # Create your views here.
     
     
    class Test(views.View):
        def get(self,request):
            print(request,type(request))
            return HttpResponse("ok")
     
        def post(self):
            pass
     
     
     
    from rest_framework import serializers
    from app1 import models
    from rest_framework.views import APIView
    from rest_framework.response import Response
     
    from app1.serializer import *
     
    class Book_modelserializer_cbv(APIView):
        def get(self,request):
     
            queryset_list = models.Book.objects.all()
            ret = bookmodelserializers(queryset_list,many=True)
            print(dir(ret),type(ret))
            return Response(ret.data)
     
     
     
        def post(self,request):
     
            ret = bookmodelserializers(data=request.data)
            print("request.data",request.data,"==============================")
            if ret.is_valid():
                ret.save()
                return Response(ret.data)
            else:
                return Response(ret.errors)
     
     
    class Book_Detail_modelserializer_cbv(APIView):
        def get(self,request,bid):
            obj = models.Book.objects.filter(id=bid).first()
     
            ret = bookmodelserializers(obj,many=False,context={'request': request})
            return Response(ret.data)
     
        def put(self,request,bid):
            obj = models.Book.objects.get(id=bid)
            bs = bookmodelserializers(obj,data=request.data)
            if bs.is_valid():
                bs.save()
                return Response(bs.data)
            else:
                return Response(bs.errors)
     
     
     
        def delete(self,request,bid):
            models.Book.objects.get(id=bid).delete()
            return HttpResponse("删除成功")
     
     
    from django.urls import reverse
     
    class Pub_Detail_modelserializer_cbv(APIView):
        def get(self,request,pid):
            obj = models.Publish.objects.filter(id=pid).first()
     
            ret = pubmodelserializers(obj,many=False,context={'request': request})
            s = reverse("app1:pub_detail",kwargs={"pid":int(pid)})
     
            return Response(ret.data)
     
        def put(self,request,pid):
            obj = models.Publish.objects.get(id=pid)
            bs = pubmodelserializers(obj,data=request.data,)
            if bs.is_valid():
                bs.save()
                return Response(bs.data)
            else:
                return Response(bs.errors)
     
     
     
        def delete(self,request,pid):
            models.Publish.objects.get(id=pid).delete()
            return HttpResponse("删除成功")
    

      

  • 相关阅读:
    Retrofit2源码分析
    Android8.0硬件加速的重绘流程
    Android单元测试
    rand5->rand7,rand7->rand10
    快速排序的随机化版本
    快速排序
    亦或实现交换
    在最坏情况下,找到n个元素中第二小的元素需要n+lgn-2次比较
    3*n/2时间内求出最大最小值
    基数排序
  • 原文地址:https://www.cnblogs.com/bainianminguo/p/10459458.html
Copyright © 2011-2022 走看看