加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

DRF 序列化组件

发布时间:2020-12-15 17:17:40 所属栏目:大数据 来源:网络整理
导读:Serializers 序列化组件 Django的序列化方法 = Book.objects.values( , , , , = ret = book = = Publish.objects.filter(pk=book[ ] = ] = ] = = json.dumps(book_list,ensure_ascii=False,cls= span style="color: #008000;"# span style="color: #008000;"

Serializers 序列化组件

Django的序列化方法

= Book.objects.values(,,,,= ret = book == Publish.objects.filter(pk=book[] =] =] == json.dumps(book_list,ensure_ascii=False,cls=<span style="color: #008000;">#<span style="color: #008000;"> json.JSONEncoder.default()<span style="color: #008000;">

<span style="color: #008000;"> 解决json不能序列化时间字段的问题

<span style="color: #0000ff;">class<span style="color: #000000;"> MyJson(json.JSONEncoder):
<span style="color: #0000ff;">def<span style="color: #000000;"> default(self,field):
<span style="color: #0000ff;">if<span style="color: #000000;"> isinstance(field,datetime.datetime):
<span style="color: #0000ff;">return field.strftime(<span style="color: #800000;">'<span style="color: #800000;">%Y-%m-%d %H:%M:%S<span style="color: #800000;">'<span style="color: #000000;">)
<span style="color: #0000ff;">elif<span style="color: #000000;"> isinstance(field,datetime.date):
<span style="color: #0000ff;">return field.strftime(<span style="color: #800000;">'<span style="color: #800000;">%Y-%m-%d<span style="color: #800000;">'<span style="color: #000000;">)
<span style="color: #0000ff;">else<span style="color: #000000;">:
<span style="color: #0000ff;">return json.JSONEncoder.default(self,field)

django.core <span style="color: #008000;">#<span style="color: #008000;"> 能够得到我们要的效果 结构有点复杂
<span style="color: #0000ff;">class<span style="color: #000000;"> BooksView(View):
<span style="color: #0000ff;">def<span style="color: #000000;"> get(self,request):
book_list =<span style="color: #000000;"> Book.objects.all()
ret = serializers.serialize(<span style="color: #800000;">"<span style="color: #800000;">json<span style="color: #800000;">"<span style="color: #000000;">,book_list)
<span style="color: #0000ff;">return HttpResponse(ret)

DRF序列化的方法

首先,我们要用DRF的序列化,就要遵循人家框架的一些标准,

  -- Django我们CBV继承类是View,现在DRF我们要用APIView

  -- Django中返回的时候我们用HTTPResponse,JsonResponse,render ,DRF我们用Response

为什么这么用~我们之后会详细讲~~我们继续来看序列化~~

序列化

== serializers.CharField(max_length=32= ((1,),(2,),(3,= serializers.ChoiceField(choices=CHOICES,source== serializers.DateField()
rest_framework.views rest_framework.response <span style="color: #0000ff;">class<span style="color: #000000;"> BookView(APIView):
<span style="color: #0000ff;">def
<span style="color: #000000;"> get(self,request):
book_list
=<span style="color: #000000;"> Book.objects.all()
ret
= BookSerializer(book_list,many=<span style="color: #000000;">True)
<span style="color: #0000ff;">return Response(ret.data)

外键关系的序列化

rest_framework .models <span style="color: #0000ff;">class<span style="color: #000000;"> PublisherSerializer(serializers.Serializer):
id
= serializers.IntegerField(read_only=<span style="color: #000000;">True)
title
= serializers.CharField(max_length=32<span style="color: #000000;">)

<span style="color: #0000ff;">class<span style="color: #000000;"> UserSerializer(serializers.Serializer):
id = serializers.IntegerField(read_only=<span style="color: #000000;">True)
name = serializers.CharField(max_length=32<span style="color: #000000;">)
age =<span style="color: #000000;"> serializers.IntegerField()

<span style="color: #0000ff;">class<span style="color: #000000;"> BookSerializer(serializers.Serializer):
id = serializers.IntegerField(read_only=<span style="color: #000000;">True)
title = serializers.CharField(max_length=32<span style="color: #000000;">)
CHOICES = ((1,source=<span style="color: #800000;">"<span style="color: #800000;">get_chapter_display<span style="color: #800000;">",read_only=<span style="color: #000000;">True)
pub_time =<span style="color: #000000;"> serializers.DateField()

publisher </span>= PublisherSerializer(read_only=<span style="color: #000000;"&gt;True)
user </span>= UserSerializer(many=True,read_only=True)</pre>

反序列化

当前端给我们发post的请求的时候~前端给我们传过来的数据~我们要进行一些校验然后保存到数据库~

这些校验以及保存工作,DRF的Serializer也给我们提供了一些方法了~~

首先~我们要写反序列化用的一些字段~有些字段要跟序列化区分开~~

Serializer提供了.is_valid()? 和.save()方法~~

= serializers.IntegerField(read_only== serializers.CharField(max_length=32= ((1,read_only== serializers.IntegerField(write_only==publisher </span>= PublisherSerializer(read_only=<span style="color: #000000;"&gt;True) user </span>= UserSerializer(many=True,read_only=<span style="color: #000000;"&gt;True) users </span>= serializers.ListField(write_only=<span style="color: #000000;"&gt;True) publisher_id </span>= serializers.IntegerField(write_only=<span style="color: #000000;"&gt;True) </span><span style="color: #0000ff;"&gt;def</span><span style="color: #000000;"&gt; create(self,validated_data): book </span>= Book.objects.create(title=validated_data[<span style="color: #800000;"&gt;"</span><span style="color: #800000;"&gt;title</span><span style="color: #800000;"&gt;"</span>],chapter=validated_data[<span style="color: #800000;"&gt;"</span><span style="color: #800000;"&gt;w_chapter</span><span style="color: #800000;"&gt;"</span>],pub_time=validated_data[<span style="color: #800000;"&gt;"</span><span style="color: #800000;"&gt;pub_time</span><span style="color: #800000;"&gt;"</span>],publisher_id=validated_data[<span style="color: #800000;"&gt;"</span><span style="color: #800000;"&gt;publisher_id</span><span style="color: #800000;"&gt;"</span><span style="color: #000000;"&gt;]) book.user.add(</span>*validated_data[<span style="color: #800000;"&gt;"</span><span style="color: #800000;"&gt;users</span><span style="color: #800000;"&gt;"</span><span style="color: #000000;"&gt;]) </span><span style="color: #0000ff;"&gt;return</span> book</pre>
</span><span style="color: #0000ff;"&gt;def</span><span style="color: #000000;"&gt; post(self,request): </span><span style="color: #008000;"&gt;#</span><span style="color: #008000;"&gt; book_obj = request.data</span> <span style="color: #0000ff;"&gt;print</span><span style="color: #000000;"&gt;(request.data) serializer </span>= BookSerializer(data=<span style="color: #000000;"&gt;request.data) </span><span style="color: #0000ff;"&gt;if</span><span style="color: #000000;"&gt; serializer.is_valid(): </span><span style="color: #0000ff;"&gt;print</span>(12341253<span style="color: #000000;"&gt;) serializer.save() </span><span style="color: #0000ff;"&gt;return</span><span style="color: #000000;"&gt; Response(serializer.validated_data) </span><span style="color: #0000ff;"&gt;else</span><span style="color: #000000;"&gt;: </span><span style="color: #0000ff;"&gt;return</span> Response(serializer.errors)</pre>

但前端给我们发送patch请求的时候,前端传给我们用户需要更新的数据,我们要对数据进行部分验证.

= serializers.IntegerField(read_only== serializers.CharField(max_length=32= ((1,pub_time=validated_data[=validated_data[*validated_data[</span><span style="color: #0000ff;"&gt;def</span><span style="color: #000000;"&gt; update(self,instance,validated_data): instance.title </span>= validated_data.get(<span style="color: #800000;"&gt;"</span><span style="color: #800000;"&gt;title</span><span style="color: #800000;"&gt;"</span><span style="color: #000000;"&gt;,instance.title) instance.chapter </span>= validated_data.get(<span style="color: #800000;"&gt;"</span><span style="color: #800000;"&gt;w_chapter</span><span style="color: #800000;"&gt;"</span><span style="color: #000000;"&gt;,instance.chapter) instance.pub_time </span>= validated_data.get(<span style="color: #800000;"&gt;"</span><span style="color: #800000;"&gt;pub_time</span><span style="color: #800000;"&gt;"</span><span style="color: #000000;"&gt;,instance.pub_time) instance.publisher_id </span>= validated_data.get(<span style="color: #800000;"&gt;"</span><span style="color: #800000;"&gt;publisher_id</span><span style="color: #800000;"&gt;"</span><span style="color: #000000;"&gt;,instance.publisher_id) </span><span style="color: #0000ff;"&gt;if</span> validated_data.get(<span style="color: #800000;"&gt;"</span><span style="color: #800000;"&gt;users</span><span style="color: #800000;"&gt;"</span><span style="color: #000000;"&gt;): instance.user.set(validated_data.get(</span><span style="color: #800000;"&gt;"</span><span style="color: #800000;"&gt;users</span><span style="color: #800000;"&gt;"</span><span style="color: #000000;"&gt;)) instance.save() </span><span style="color: #0000ff;"&gt;return</span> instance</pre>
= request.data[= request.data[= Book.objects.filter(pk== BookSerializer(book_obj,data=book_info,partial= Response(serializer.errors)

?验证

如果我们需要对一些字段进行自定义的验证~DRF也给我们提供了钩子方法.

= serializers.IntegerField(read_only== serializers.CharField(max_length=32 serializers.ValidationError( value
= serializers.IntegerField(read_only== serializers.CharField(max_length=32= ((1,read_only== serializers.IntegerField(write_only=== serializers.DateField(write_only=
<span style="color: #008000;"&gt;#</span><span style="color: #008000;"&gt; 对多个字段进行验证 要求上架日期不能早于出版日期 上架日期要大</span>
<span style="color: #0000ff;"&gt;def</span><span style="color: #000000;"&gt; validate(self,attrs):
    </span><span style="color: #0000ff;"&gt;if</span> attrs[<span style="color: #800000;"&gt;"</span><span style="color: #800000;"&gt;pub_time</span><span style="color: #800000;"&gt;"</span>] > attrs[<span style="color: #800000;"&gt;"</span><span style="color: #800000;"&gt;date_added</span><span style="color: #800000;"&gt;"</span><span style="color: #000000;"&gt;]:
        </span><span style="color: #0000ff;"&gt;raise</span> serializers.ValidationError(<span style="color: #800000;"&gt;"</span><span style="color: #800000;"&gt;上架日期不能早于出版日期</span><span style="color: #800000;"&gt;"</span><span style="color: #000000;"&gt;)
    </span><span style="color: #0000ff;"&gt;return</span> attrs</pre>
serializers.ValidationError(<span style="color: #0000ff;">class<span style="color: #000000;"> BookSerializer(serializers.Serializer):
id
= serializers.IntegerField(read_only=<span style="color: #000000;">True)
title
= serializers.CharField(max_length=32,validators=<span style="color: #000000;">[my_validate])
<span style="color: #008000;">#
<span style="color: #008000;"> 。。。。。。

ModelSerializer

现在我们已经清楚了Serializer的用法,会发现我们所有的序列化跟我们的模型都紧密相关~

那么,DRF也给我们提供了跟模型紧密相关的序列化器~~ModelSerializer~~

  -- 它会根据模型自动生成一组字段

  -- 它简单的默认实现了.update()以及.create()方法

定义一个ModelSerializer序列化器

==

外键关系的序列化

注意:当序列化类MATE中定义了depth时,这个序列化类中引用字段(外键)则自动变为只读

== depth = 1

自定义字段

我们可以声明一些字段来覆盖默认字段,来进行自定制~

比如我们的选择字段,默认显示的是选择的key,我们要给用户展示的是value。

= serializers.CharField(source=,read_only=</span><span style="color: #0000ff;"&gt;class</span><span style="color: #000000;"&gt; Meta: model </span>=<span style="color: #000000;"&gt; Book fields </span>= <span style="color: #800000;"&gt;"</span><span style="color: #800000;"&gt;__all__</span><span style="color: #800000;"&gt;"</span> <span style="color: #008000;"&gt;#</span><span style="color: #008000;"&gt; fields = ["id","pub_time"]</span> <span style="color: #008000;"&gt;#</span><span style="color: #008000;"&gt; exclude = ["user"]</span> <span style="color: #008000;"&gt;#</span><span style="color: #008000;"&gt; 分别是所有字段 包含某些字段 排除某些字段</span> depth = 1</pre>

Meta中其它关键字参数

= serializers.CharField(source=,read_only=</span><span style="color: #0000ff;"&gt;class</span><span style="color: #000000;"&gt; Meta: model </span>=<span style="color: #000000;"&gt; Book fields </span>= <span style="color: #800000;"&gt;"</span><span style="color: #800000;"&gt;__all__</span><span style="color: #800000;"&gt;"</span> <span style="color: #008000;"&gt;#</span><span style="color: #008000;"&gt; fields = ["id","pub_time"]</span> <span style="color: #008000;"&gt;#</span><span style="color: #008000;"&gt; exclude = ["user"]</span> <span style="color: #008000;"&gt;#</span><span style="color: #008000;"&gt; 分别是所有字段 包含某些字段 排除某些字段</span> depth = 1<span style="color: #000000;"&gt; read_only_fields </span>= [<span style="color: #800000;"&gt;"</span><span style="color: #800000;"&gt;id</span><span style="color: #800000;"&gt;"</span><span style="color: #000000;"&gt;] extra_kwargs </span>= {<span style="color: #800000;"&gt;"</span><span style="color: #800000;"&gt;title</span><span style="color: #800000;"&gt;"</span>: {<span style="color: #800000;"&gt;"</span><span style="color: #800000;"&gt;validators</span><span style="color: #800000;"&gt;"</span>: [my_validate,]}}</pre>

post以及patch请求

由于depth会让我们外键变成只读,所以我们再定义一个序列化的类,其实只要去掉depth就可以了

= serializers.CharField(source=,"pub_time"] read_only_fields = [= {: {: [my_validate,]}}

SerializerMethodField

外键关联的对象有很多字段我们是用不到的~都传给前端会有数据冗余~就需要我们自己去定制序列化外键对象的哪些字段~~

= serializers.CharField(source=,read_only===</span><span style="color: #0000ff;"&gt;def</span><span style="color: #000000;"&gt; get_user(self,obj): </span><span style="color: #008000;"&gt;#</span><span style="color: #008000;"&gt; obj是当前序列化的book对象</span> users_query_set =<span style="color: #000000;"&gt; obj.user.all() </span><span style="color: #0000ff;"&gt;return</span> [{<span style="color: #800000;"&gt;"</span><span style="color: #800000;"&gt;id</span><span style="color: #800000;"&gt;"</span>: user_obj.pk,<span style="color: #800000;"&gt;"</span><span style="color: #800000;"&gt;name</span><span style="color: #800000;"&gt;"</span>: user_obj.name} <span style="color: #0000ff;"&gt;for</span> user_obj <span style="color: #0000ff;"&gt;in</span><span style="color: #000000;"&gt; users_query_set] </span><span style="color: #0000ff;"&gt;def</span><span style="color: #000000;"&gt; get_publisher(self,obj): publisher_obj </span>=<span style="color: #000000;"&gt; obj.publisher </span><span style="color: #0000ff;"&gt;return</span> {<span style="color: #800000;"&gt;"</span><span style="color: #800000;"&gt;id</span><span style="color: #800000;"&gt;"</span>: publisher_obj.pk,<span style="color: #800000;"&gt;"</span><span style="color: #800000;"&gt;title</span><span style="color: #800000;"&gt;"</span><span style="color: #000000;"&gt;: publisher_obj.title} </span><span style="color: #0000ff;"&gt;class</span><span style="color: #000000;"&gt; Meta: model </span>=<span style="color: #000000;"&gt; Book fields </span>= <span style="color: #800000;"&gt;"</span><span style="color: #800000;"&gt;__all__</span><span style="color: #800000;"&gt;"</span> <span style="color: #008000;"&gt;#</span><span style="color: #008000;"&gt; fields = ["id",]}}</pre>

用ModelSerializer改进上面Serializer的完整版

= serializers.SerializerMethodField(read_only== serializers.SerializerMethodField(read_only== serializers.SerializerMethodField(read_only=</span><span style="color: #0000ff;"&gt;def</span><span style="color: #000000;"&gt; get_users(self,<span style="color: #800000;"&gt;"</span><span style="color: #800000;"&gt;name</span><span style="color: #800000;"&gt;"</span>: user_obj.name} <span style="color: #0000ff;"&gt;for</span> user_obj <span style="color: #0000ff;"&gt;in</span><span style="color: #000000;"&gt; users_query_set] </span><span style="color: #0000ff;"&gt;def</span><span style="color: #000000;"&gt; get_publishers(self,<span style="color: #800000;"&gt;"</span><span style="color: #800000;"&gt;title</span><span style="color: #800000;"&gt;"</span><span style="color: #000000;"&gt;: publisher_obj.title} </span><span style="color: #0000ff;"&gt;def</span><span style="color: #000000;"&gt; get_dis_chapter(self,obj): </span><span style="color: #0000ff;"&gt;return</span><span style="color: #000000;"&gt; obj.get_chapter_display() </span><span style="color: #0000ff;"&gt;class</span><span style="color: #000000;"&gt; Meta: model </span>=<span style="color: #000000;"&gt; Book </span><span style="color: #008000;"&gt;#</span><span style="color: #008000;"&gt; fields = "__all__"</span> <span style="color: #008000;"&gt;#</span><span style="color: #008000;"&gt; 字段是有序的</span> fields = [<span style="color: #800000;"&gt;"</span><span style="color: #800000;"&gt;id</span><span style="color: #800000;"&gt;"</span>,<span style="color: #800000;"&gt;"</span><span style="color: #800000;"&gt;dis_chapter</span><span style="color: #800000;"&gt;"</span>,<span style="color: #800000;"&gt;"</span><span style="color: #800000;"&gt;publishers</span><span style="color: #800000;"&gt;"</span>,<span style="color: #800000;"&gt;"</span><span style="color: #800000;"&gt;users</span><span style="color: #800000;"&gt;"</span>,<span style="color: #800000;"&gt;"</span><span style="color: #800000;"&gt;user</span><span style="color: #800000;"&gt;"</span>,<span style="color: #800000;"&gt;"</span><span style="color: #800000;"&gt;publisher</span><span style="color: #800000;"&gt;"</span><span style="color: #000000;"&gt;] </span><span style="color: #008000;"&gt;#</span><span style="color: #008000;"&gt; exclude = ["user"]</span> <span style="color: #008000;"&gt;#</span><span style="color: #008000;"&gt; 分别是所有字段 包含某些字段 排除某些字段</span> read_only_fields = [<span style="color: #800000;"&gt;"</span><span style="color: #800000;"&gt;id</span><span style="color: #800000;"&gt;"</span>,<span style="color: #800000;"&gt;"</span><span style="color: #800000;"&gt;publishers</span><span style="color: #800000;"&gt;"</span><span style="color: #000000;"&gt;] extra_kwargs </span>= {<span style="color: #800000;"&gt;"</span><span style="color: #800000;"&gt;title</span><span style="color: #800000;"&gt;"</span>: {<span style="color: #800000;"&gt;"</span><span style="color: #800000;"&gt;validators</span><span style="color: #800000;"&gt;"</span>: [my_validate,]},<span style="color: #800000;"&gt;"</span><span style="color: #800000;"&gt;user</span><span style="color: #800000;"&gt;"</span>: {<span style="color: #800000;"&gt;"</span><span style="color: #800000;"&gt;write_only</span><span style="color: #800000;"&gt;"</span>: True},<span style="color: #800000;"&gt;"</span><span style="color: #800000;"&gt;publisher</span><span style="color: #800000;"&gt;"</span>: {<span style="color: #800000;"&gt;"</span><span style="color: #800000;"&gt;write_only</span><span style="color: #800000;"&gt;"</span><span style="color: #000000;"&gt;: True},</span><span style="color: #800000;"&gt;"</span><span style="color: #800000;"&gt;chapter</span><span style="color: #800000;"&gt;"</span>: {<span style="color: #800000;"&gt;"</span><span style="color: #800000;"&gt;write_only</span><span style="color: #800000;"&gt;"</span>: True}}</pre>

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读