ModelSerializer 和 serializers

serializers序列化:普通字段

# 一.定义一个反序列的类
from rest_framework import serializers
from rest_framework.response import Response

# 为queryset, model对象做序列化,只要你定义了name和addr我都能给你反序列化
class PublishSerializers(serializers.Serializer):
    name = serializers.CharField()
    addr = serializers.CharField()
#使用
class PublishView(APIView):
    # 查询数据
    def get(self, request):
        # first inquire database
        publish = models.Publisher.objects.all()
        # data put serializers data packging
        bs = PublishSerializers(publish, many=True)  # many=True多个对象
        # return
        return Response(bs.data)

serializers序列化:一对多,多对多

class BookSerializers(serializers.Serializer):
    title = serializers.CharField()
    pub_date = serializers.DateField()
    # 反序列化一对多字段返回的是__str__数据
    publish = serializers.CharField(source="publish.addr")  # source 可以指定返回的一对多的字段
    # authors=serializers.CharField(source="authors.all")  # 指定序列化多对多的字段
    authors = serializers.SerializerMethodField()

    # 多对多字段序列化方法,这个函数必须是get_authors,因为这个字段在是多对多
    def get_authors(self, obj):
        temp = []
        for obj in obj.authors.all():
            temp.append(obj.name)
        return temp
#使用
class PublishView(APIView):
    # 查询数据
    def get(self, request):
        # first inquire database
        publish = models.Publisher.objects.all()
        # data put serializers data packging
        bs = BookSerializers(publish, many=True)  # many=True多个对象
        # return
        return Response(bs.data)

ModelSerializer
在大多数情况下,我们都是基于model字段去开发。

ModelSerializerSerializer区别在于ModelSerializer支持了Serializer中所有的操作,并且通过自动生成所有数据字段与序列化类的一一对应关系,而不用自己手动添加。
SerializerModelSerializer的父类,所以ModelSerializer才会支持Serializer的所有操作

好处:
ModelSerializer已经重载了create与update方法,它能够满足将post或patch上来的数据进行进行直接地创建与更新,除非有额外需求,那么就可以重载create与update方法。
  ModelSerializer在Meta中设置fields字段,系统会自动进行映射,省去每个字段再写一个field

序列化原理:

"""
序列化原理BookSerializers(book_list,many=Ture):
    temp=[]
        for obj in book_list:
            temp.append({
            "title":obj.title,
            "price":str(obj.publish), #obj.publish.name
            "author":get_authors(obj),

            })

"""
# 定义一个model类
class PublishModelSerializers(serializers.ModelSerializer):
    class Meta:
        model = models.Publisher
        fields = "__all__" #  表示所有字段
        # exclude = (‘add_time‘,):  除去指定的某些字段
        # 定义报错信息
        # extra_kwargs = {
        #     "content": {"error_messages": {"required": "评论内容不能为空"}},
        #     "article": {"error_messages": {"required": "文章不能为空"}}
        # }

查询全部字段的数据:

class PublishView(APIView):
    # 查询数据
    def get(self, request):
        # first inquire database
        publish = models.Publisher.objects.all()
        # data put serializers data packging
        bs = PublishModelSerializers(publish, many=True)  # many=True多个对象
        # return
        return Response(bs.data)

    # 增加数据
    def post(self, request):
        bs = PublishModelSerializers(data=request.data)  # post不需要定义many=Ture
        if bs.is_valid():
            bs.save()  # 保存
            return Response("添加成功")
        else:
            return Response("增加失败")

查询带个数据:

class PublishDetaiView(APIView):
    # 将这个pk设置成和lookup_url_kwarg=‘pk‘ 一样的值,不然加后缀会取不到值
    def get(self, request, pk):  # id 不要放到request前面
        # 查询数据库
        publish = models.Publisher.objects.filter(pk=pk)
        # 封装打包序列化数据
        bs = PublishModelSerializers(publish, many=True)  # many=True多个对象
        # Response 会直接返回josn数据格式
        return Response(bs.data)

    # #  修改数据(前端指定id值后,在data中输入k:v即可change数据)
    def put(self, request, pk):
        # inquire database
        publish = models.Publisher.objects.filter(pk=pk).first()
        # data=  form request.data client
        ps = PublishModelSerializers(publish, data=request.data, many=True)  # many=True多个对象
        # if ps pass verify
        if ps.is_valid():
            ps.save()
            return Response(ps.data)
        else:
            return Response(ps.errors)

    # 删除数据(功能还未实现)
    # def delete(self, request, pk):
    #     models.Publisher.objects.filter(pk=pk).delete()
    #     return Response("删除成功")

一对多和多对多的形式

class BookModelSerializers(serializers.ModelSerializer):
    # 自定义publish字段超链接路径
    # depth = 1  # 0 ~ 10
    # publish = serializers.HyperlinkedIdentityField(view_name=‘detailpublish‘,
    #                                                lookup_field=‘publish_id‘,
    #                                                lookup_url_kwarg=‘pk‘)

    """
    # view_name参数 进行传参的时候是参考路由匹配中的name与namespace参数
    #  lookeup_field参数是根据在UserInfo表中的连表查询字段group_id
    # look_url_kwarg参数在做url反向解析的时候会用到
    """

    class Meta:
        model = models.Book
        # fields = [‘id‘, ‘title‘, ‘pub_date‘, ‘publish‘, ‘authors‘]# 这个是可以自定义字段的
        fields = "__all__"
        depth = 0
        # 自动向内部进行深度查询,就是查询的比较详细  depth表示查询层数
class BookView(APIView):
    def get(self, request, *args, **kwargs):
        book_list = models.Book.objects.all()
        # context十分关键,如果不将request传递给它,在序列化的时候,图片与文件这些Field不会再前面加上域名,也就是说,只会有/media/img...这样的路径!
        bs = BookModelSerializers(instance=book_list, many=True)  # 在做链接的时候需要添加context参数
        print(bs)
        # 默认就返回json格式的字符串
        return Response(bs.data)

    # 其他还未实现

class BookDetaiView(APIView):
    # inquire database
    def get(self, request, id, *args, **kwargs):
        book_list = models.Book.objects.filter(id=id)
        bs = BookModelSerializers(instance=book_list, many=True)  # 在做链接的时候需要添加context参数
        print(bs)
        # 默认就返回json格式的字符串
        return Response(bs.data)

        # 其他还未实现
自定义字段超链接路径
class BookModelSerializers(serializers.ModelSerializer):
    # 自定义publish字段超链接路径
    depth = 1  # 0 ~ 10
    publish = serializers.HyperlinkedIdentityField(view_name=‘detailpublish‘,
                                                   lookup_field=‘publish_id‘,
                                                   lookup_url_kwarg=‘pk‘)

    """
    # view_name参数 进行传参的时候是参考路由匹配中的name与namespace参数
    #  lookeup_field参数是根据在UserInfo表中的连表查询字段group_id
    # look_url_kwarg参数在做url反向解析的时候会用到
    """

    class Meta:
        model = models.Book
        # fields = [‘id‘, ‘title‘, ‘pub_date‘, ‘publish‘, ‘authors‘]
        fields = "__all__"
        depth = 0
        # 自动向内部进行深度查询,就是查询的比较详细  depth表示查询层数

总结:

1.request类---------源码

2.restframework 下的APIView

re_path(‘^books/$‘, views.BookView.as_view(),name="book"),  # View(request) ======APIView:dispatch()

  books/一旦被访问: view(request) ---------dispatch()

3.dispatch()

  构建request对象

  self.request=Request(request)

  self.request._request

  self.request._GET

  self.request._data  # POST  PUT

  分发-------get请求(源码)

     if request.method.lower() in self.http_method_names:
            # self = Publish,反射类中的get方法如果有我就封装到handler里面,如果你没有定义方法我我也就返回一个错误信息
            handler = getattr(self, request.method.lower(), self.http_method_not_allowed)
        else:
            # <HttpResponseNotAllowed [OPTIONS] status_code=405, "text/html; charset=utf-8">
            handler = self.http_method_not_allowed
            #也就是说这个地方要么就是调用我Publish的get方法和post方法,要不就抛错误信息
        return handler(request, *args, **kwargs)  #self.get      # 相当于调用了get()方法的response

4. 序列化类

 # from django,core import serializers

# ret = serializers.serialize("json",publish_list)

  restframework下的序列化类

    将queryset或者model对象序列化成一个json数据

      bs = BookModelSerializers(instance=book_list, many=True, context={‘request‘: request})  # 在做链接的时候需要添加context参数      # 默认就返回json格式的字符串      return Response(bs.data)      还可以做校验数据, json ------> queryset/model------》记录
        ps = PublishModelSerializers(publish, data=request.data, many=True)  # many=True多个对象
        # 做校验数据
        if ps.is_valid():
            ps.save()
            return Response(ps.data)
        else:
            return Response(ps.errors)

5.操作数据(例)

    

class PublishView(APIView):
    # 查询数据
    def get(self, request):
        # first inquire database
        publish = models.Publisher.objects.all()
        # data put serializers data packging
        bs = PublishModelSerializers(publish, many=True)  # many=True多个对象
        # return
        return Response(bs.data)

    # 增加数据
    def post(self, request):
        bs = PublishModelSerializers(data=request.data)  # post不需要定义many=Ture
        if bs.is_valid():
            bs.save()  # 保存
            return Response("添加成功")
        else:
            return Response("增加失败")

class PublishDetaiView(APIView):
    # 将这个pk设置成和lookup_url_kwarg=‘pk‘ 一样的值,不然加后缀会取不到值
    def get(self, request, pk):  # id 不要放到request前面
        # 查询数据库
        publish = models.Publisher.objects.filter(pk=pk)
        # 封装打包序列化数据
        bs = PublishModelSerializers(publish, many=True)  # many=True多个对象
        # Response 会直接返回josn数据格式
        ret = Response(bs.data)
        # print(ret,6666666666666666666666666)
        return ret

    # #  修改数据(前端指定id值后,在data中输入k:v即可change数据)
    def put(self, request, pk):
        # inquire database
        publish = models.Publisher.objects.filter(pk=pk).first()
        # data=  form request.data client
        ps = PublishModelSerializers(publish, data=request.data, many=True)  # many=True多个对象
        # if ps pass verify
        if ps.is_valid():
            ps.save()
            return Response(ps.data)
        else:
            return Response(ps.errors)

    # 删除数据(功能还未实现)
    # def delete(self, request, pk):
    #     models.Publisher.objects.filter(pk=pk).delete()
    #     return Response("删除成功")

      

    

原文地址:https://www.cnblogs.com/Rivend/p/11823763.html

时间: 2024-08-30 18:01:53

ModelSerializer 和 serializers的相关文章

django rest_framework Serializers 序列化组件

为什么要用序列化组件 当我们做前后端分离的项目~~我们前后端交互一般都选择JSON数据格式,JSON是一个轻量级的数据交互格式. 那么我们给前端数据的时候都要转成json格式,那就需要对我们从数据库拿到的数据进行序列化. 接下来我们看下django序列化和rest_framework序列化的对比~~ Django的序列化方法 class BooksView(View): def get(self, request): book_list = Book.objects.values("id&quo

Django Rest Framework(2)-----序列化详解(serializers)

REST framework中的序列化类与Django的Form和ModelForm类非常相似.我们提供了一个Serializer类,它提供了一种强大的通用方法来控制响应的输出,以及一个ModelSerializer类,它为创建处理模型实例和查询集的序列化提供了有效的快捷方式. Serializers 序列化器允许把像查询集和模型实例这样的复杂数据转换为可以轻松渲染成JSON,XML或其他内容类型的原生Python类型.序列化器还提供反序列化,在验证传入的数据之后允许解析数据转换回复杂类型.不仅

一,Serializer和ModelSerializer

1.REST Framework概述 Django REST framework是一套基于Django的REST框架,是一个用于构建Web API的功能强大且灵活的工具包. RESTful 简述 Representational State Transfer(REST),是一种架构样式,定义了一套用于创建WEB服务的约束.当前WEB开发趋势就是前端层出不穷,为了保证一个后台同时适用于多个前端,需要一种统一的机制或API,而RESTful API是目前前后端分离的最佳实践. 为什么需要前后端分离?

Drf 序列化 ModelSerializer跨表取数据

1.对于OneToOne.Foreignkey.choices字段可以使用source取出相关信息: class CourseSerializer(serializers.ModelSerializer): # choices字段 degree = serializers.CharField(source='get_degree_display') # ForeignKey字段 teacher = serializers.CharField(source='teacher.name') clas

序列化器:ModelSerializer

ModelSerializer 类提供了一个快捷方式,可让你基于 Models 自动创建一个 Serializer 类,其中的字段与模型类字段对应. ModelSerializer 类与常规 Serializer 类相同,不同之处在于: 它会根据模型自动生成一组字段. 它会自动为序列化类生成验证器,例如 unique_together 验证器. 它包含 .create() 和 .update() 的简单默认实现. 声明 ModelSerializer 如下所示: from rest_framew

ModelSerializer字段验证的扩展操作

def validate_字段名(self, value),单一字段校验 from rest_framework import serializers from rest_framework import exceptions from .. import models class BidModelSerializer(serializers.ModelSerializer): username = serializers.CharField(source='user.nickname', re

Django-rest-framework多条件查询/分页/多表Json

Django-rest-framework多条件查询/分页/多表Json django-rest-framework多条件查询需要覆写ListAPIView.get_queryset方法,代码示例: def get_queryset(self):     """     使用request.query_params实现多条件查询,也可以使用django filter ,较简单的     方法是在filter_fields中指定要过滤的字段,但只能表示等值,不灵活,灵活的方式是

一个比较全面的DJANGO_REST_FRAMEWORK的CASE

验证啊,过滤啊,hypermedia as the engine of ap‐plication state (HATEOAS)啊都有的. urls.py __author__ = 'sahara' from rest_framework.routers import DefaultRouter from . import views router = DefaultRouter() router.register(r'sprints', views.SprintViewSet) router.

django_restframework_angularjs

用Django Rest Framework和AngularJS开始你的项目 作者: seele52 发布时间:2015-07-29 11:30:55 用Django Rest Framework和AngularJS开始你的项目 作者:Kevin Stone原帖:Getting Started with Django Rest Framework and AngularJS原帖时间:2013-10-02 译序:虽然本文号称是"hello world式的教程"(这么长的hello wor