当前位置:网站首页>Serializer & modelserializer of DRF serialization and deserialization
Serializer & modelserializer of DRF serialization and deserialization
2022-07-07 09:11:00 【FOR. GET】
- One 、 serialize : The model is converted to JSON technological process ( Transmission only instance)
- Two 、 Commonly used serialized fields and parameters
- 3、 ... and 、 Deserialization :JSON Convert to model process ( Just pass it on data)
- Four 、 Model serializer class instructions
One 、 serialize : The model is converted to JSON technological process ( Transmission only instance)
- Serialized classes should be created separately in this application
serializers.py
To write the- Define serializer class ( The model name / Class view name +
Serializer
), And inherit fromSerializer
- Define the fields in the serializer to refer to Model (
models.py
), The field name in the serializer needs to be consistent with the model , Fields can be more or less than model fields - For fields with foreign keys (
OneToOneField
、ManyToManyField
、ForeignKey
), When serialization is associated with foreign key fields Foreign key name , Associated serialization in fields without foreign keys is often used The model name is lowercase _set - When serializing an association without a foreign key, you need to specify the associated field
many=true
- The model object or query set will be serialized ( Multiple model objects ), Passed to the serializer class
instance
Parameters , If the transmitted query set needs to be specifiedmany=true
- Get serialized data , adopt
Serializer object .data
Property to get - Serialization is just a model to dictionary
- Define serializer class ( The model name / Class view name +
1.1 Creating a data model
After creating the data model , Add some test data in the background
from django.db import models
class Book(models.Model):
title = models.CharField(max_length=32)
created_time = models.DateField(auto_now_add=True)
publish = models.ForeignKey('Publish',on_delete=models.CASCADE)
class Meta: # Model meta options
# db_table = 'tb_column' # Table name in the database , otherwise Django Automatically become app name _ Class name
# ordering = ['index']
verbose_name = ' Title '
verbose_name_plural = verbose_name
def __str__(self):
return self.title
class Author(models.Model):
name = models.CharField(max_length=20)
book = models.ManyToManyField(Book)
class Meta: # Model meta options
# db_table = 'tb_column' # Table name in the database , otherwise Django Automatically become app name _ Class name
# ordering = ['index']
verbose_name = ' author '
verbose_name_plural = verbose_name
def __str__(self):
return self.name
class Publish(models.Model):
publish = models.CharField(max_length=32)
class Meta: # Model meta options
# db_table = 'tb_column' # Table name in the database , otherwise Django Automatically become app name _ Class name
# ordering = ['index']
verbose_name = ' Press. '
verbose_name_plural = verbose_name
def __str__(self):
return self.publish
class AuthorDetail(models.Model):
address = models.CharField(max_length=32)
author = models.OneToOneField(Author,on_delete=models.CASCADE)
class Meta: # Model meta options
# db_table = 'tb_column' # Table name in the database , otherwise Django Automatically become app name _ Class name
# ordering = ['index']
verbose_name = ' details '
verbose_name_plural = verbose_name
def __str__(self):
return self.address
1.2 newly build serializers.py, Simple serialization
from rest_framework import serializers
class BookSerializer(serializers.Serializer):
title = serializers.CharField(max_length=32)
created_time = serializers.DateField()
- Serialize model objects
python manage.py shell
In [3]: from book.serializers import BookSerializer
In [4]: from book.models import Book
In [5]: book = Book.objects.get(pk=1)
In [6]: ser = BookSerializer(book)
In [7]: ser.data
Out[7]: {
'title': 'Python', 'created_time': '2021-10-08'}
- Serialize the query set ( Multiple model objects ,
queryset
object )
In [1]: from book.serializers import BookSerializer
In [2]: from book.models import Book
In [3]: books = Book.objects.all()
In [4]: sers = BookSerializer(books,many=True)
In [5]: sers.data
Out[5]: [OrderedDict([('title', 'Python'), ('created_time', '2021-10-08')]), OrderedDict([('title', 'Vue'), ('created_time', '2021-10-08')])]
You need to specify multiple objects for a single acquisition
many=True
1.3 Add extra fields
- @property Define model read-only properties
# models.py by Book Model addition @property Method
class Book(models.Model):
title = models.CharField(max_length=32)
created_time = models.DateField(auto_now_add=True)
publish = models.ForeignKey('Publish',on_delete=models.CASCADE)
class Meta: # Model meta options
# db_table = 'tb_column' # Table name in the database , otherwise Django Automatically become app name _ Class name
# ordering = ['index']
verbose_name = ' Title '
verbose_name_plural = verbose_name
def __str__(self):
return self.title
# @property yes python A decorative device for , It is used to modify the method .
# We can use @property Decorators to create read-only properties ,@property The decorator converts the method to a read-only property with the same name
# , Can be used with defined properties , This prevents the property from being modified .
@property
def ext(self):
return f' Press. :name={
self.publish.publish}'
# serializers.py Serialize additional fields
from rest_framework import serializers
class BookSerializer(serializers.Serializer):
title = serializers.CharField(max_length=32)
created_time = serializers.DateField()
# Get by defining the read-only attribute of the model , This should be consistent with @propert The function names under the action of decorators are consistent
ext = serializers.CharField(max_length=20)
In [1]: from book.serializers import BookSerializer
In [2]: from book.models import Book
In [3]: books = Book.objects.all()
In [4]: sers = BookSerializer(books,many=True)
In [5]: sers.data
Out[5]: [OrderedDict([('title', 'Python'), ('created_time', '2021-10-08'), ('ext', ' Press. :name=CQJTU')]), OrderedDict([('title', 'Vue'), ('created_tim e', '2021-10-08'), ('ext', ' Press. :name=CQJTU')])]
book = Book.objects.get(pk=2)
In [7]: ser = BookSerializer(book)
In [8]: ser.data
Out[8]: {
'title': 'Vue', 'created_time': '2021-10-08', 'ext': ' Press. :name=CQJTU'}
- Customize in serializer
from django.db import models
class Book(models.Model):
title = models.CharField(max_length=32)
created_time = models.DateField(auto_now_add=True)
publish = models.ForeignKey('Publish',on_delete=models.CASCADE)
class Meta: # Model meta options
# db_table = 'tb_column' # Table name in the database , otherwise Django Automatically become app name _ Class name
# ordering = ['index']
verbose_name = ' Title '
verbose_name_plural = verbose_name
def __str__(self):
return self.title
# @property yes python A decorative device for , It is used to modify the method .
# We can use @property Decorators to create read-only properties ,@property The decorator converts the method to a read-only property with the same name
# , Can be used with defined properties , This prevents the property from being modified .
@property
def ext(self):
return f' Press. :name={
self.publish.publish}'
@property
def eee(self):
return f' author :{
[i.name for i in self.author_set.all()]}'
from rest_framework import serializers
class BookSerializer(serializers.Serializer):
title = serializers.CharField(max_length=32)
created_time = serializers.DateField()
# Get by defining the read-only attribute of the model
ext = serializers.CharField(max_length=20) # If the names correspond to the same, you do not need to specify source
author = serializers.CharField(max_length=10,source="eee") # If not, you need to specify source
# SerializerMethodField In this serialized class get_xxx To rewrite
ext_info = serializers.SerializerMethodField(label=" Extra fields ")
def get_ext_info(self,obj):
return f' Press. :{
obj.publish}'
In [1]: from book.serializers import BookSerializer
In [2]: from book.models import Book
In [3]: books = Book.objects.all()
In [4]: sers = BookSerializer(books,many=True)
In [5]: sers.data
Out[5]: [OrderedDict([('title', 'Python'), ('created_time', '2021-10-08'), ('ext', ' Press. :name=CQJTU'), ('author', " author :['AAA', 'asd']"), ('ext_info ', ' Press. :CQJTU')]), OrderedDict([('title', 'Vue'), ('created_time', '2021-10-08'), ('ext', ' Press. :name=CQJTU'), ('author', " author :['ADSD']"), ('ext _info', ' Press. :CQJTU')])]
There are two main ways to add additional fields , One is by defining the data model @property Decorator method to specify a readable only method , In this method, if the definition is the same as that of additional fields, you do not need to specify
source
, conversely ; Another is to define methods in the serialization model class to modify , By definitionget_ Additional field names
Function name method to change .
1.4 Associated object serialization
The model relationship is divided into one-to-one 、 Many to one and many to many , When we want to get the data of the associated model from a model , It can also be roughly divided into three ways , Get the primary key of the associated model (
Foreign key name _id
、PrimaryKeyRelatedField
)、 Get the corresponding__str__
The value returned by the (StringRelatedField
, Use less )、 Also, get all the fields of the associated model ( After serializing the association model you want to get , Then use the display in another serialization class ), The last one is the method of additional fields mentioned above , But there are certain limitations , Some situations cannot be well displayed , But it can also be achieved .
1.4.1 Get the primary key of the corresponding foreign key field
- ① adopt
Foreign key name _id
Get the correspondingForeign keys id
# serializers.py
from rest_framework import serializers
class BookSerializer(serializers.Serializer):
title = serializers.CharField(max_length=32)
created_time = serializers.DateField()
# stay Django ORM in , We know that the database is saved as a foreign key _id
publish_id = serializers.IntegerField()
- ②
PrimaryKeyRelatedField
, When using, you need to addread_only
perhapsqueryset
# serializers.py
class BookSerializer(serializers.Serializer):
title = serializers.CharField(max_length=32)
created_time = serializers.DateField()
# Use PrimaryKeyRelatedField Pay attention to the consistency with the fields in the model ,
# And usually you need to set `get_queryset`, or set read_only=`True`, Otherwise, the report will be wrong
# publish = serializers.PrimaryKeyRelatedField(queryset=Publish.objects.all())
publish = serializers.PrimaryKeyRelatedField(read_only=True)
In [1]: from book.serializers import BookSerializer
In [2]: from book.models import Book
In [3]: books = Book.objects.all()
In [4]: sers = BookSerializer(books,many=True)
In [5]: sers.data
Out[5]: [OrderedDict([('title', 'Python'), ('created_time', '2021-10-08'), ('publish', 1)]), OrderedDict([('title', 'Vue'), ('created_time', '2021-10-08
'), ('publish', 1)])]
1.4.2 Get the model method name associated with the foreign key __str__
Method
# serializers.py
... ditto
# Get the press __str__ Method
publish = serializers.StringRelatedField()
In [1]: from book.serializers import BookSerializer
In [2]: from book.models import Book
In [3]: books = Book.objects.all()
In [4]: sers = BookSerializer(books,many=True)
In [5]: sers.data
Out[5]: [OrderedDict([('title', 'Python'), ('created_time', '2021-10-08'), ('publish', 'CQJTU')]), OrderedDict([('title', 'Vue'), ('created_time', '2021 -10-08'), ('publish', 'CQJTU')])]
1.4.3 Get all field information of the foreign key association model
step1:
Define the serialized field information of the obtained association modelstep2:
You need to get the information in the sequence degradation field of the correlation model , And instantiate with the foreign key namestep1
Serialized model- Be careful : It must be in this order , You need to have before you can instantiate
class PublishSerializer(serializers.Serializer):
publish = serializers.CharField(max_length=32)
class BookSerializer(serializers.Serializer):
title = serializers.CharField(max_length=32)
created_time = serializers.DateField()
# Use PrimaryKeyRelatedField Pay attention to the consistency with the fields in the model ,
# And usually you need to set `get_queryset`, or set read_only=`True`, Otherwise, the report will be wrong
# publish = serializers.PrimaryKeyRelatedField(queryset=Publish.objects.all())
# publish = serializers.PrimaryKeyRelatedField(read_only=True)
# Get the press __str__ Method
publish = PublishSerializer()
1.4.4 Other instructions
- For forward queries : That is, if there is a foreign key, check if there is no foreign key ( Three relationships )
Django ORM
The model learned , The name of the foreign key saved in the database is automatically added_id
, Therefore, you can use this to obtain the primary key of foreign keys during forward query . Usually, when using foreign key Association , Without deserialization, it can be set toread_only=True
. In many to many, you need to specifymany=True
, Same as query set .
- For reverse queries : That is, query models with foreign keys without foreign keys ( The three relationships are the same )
Reverse queries can be made through
The model name is lowercase _set
To get the corresponding query set , There is no need to specify here except one-to-one relationshipmany=True
, Others need to be specifiedmany=True
. One on one, no need to add_set
Oh , Lower case table name is OK .
Two 、 Commonly used serialized fields and parameters
Official field and parameter details address
Option parameters
Parameter name | effect |
---|---|
max_length | Maximum length 32 |
min_lenght | Minimum length 2 |
allow_blank | Is it allowed to be empty False |
trim_whitespace | Whether to truncate white space characters True |
max_value | minimum value 0 |
min_value | Maximum 100 |
General parameters
Parameter name | explain |
---|---|
read_only | Indicates that this field is only used for serializing output , Default False |
write_only | Indicates that this field is only used for deserializing input , Default False |
required | Indicates whether the field must be transferred , When deserializing, you must enter , Default True. |
default | The default value to use when deserializing |
allow_null | Indicates whether the field is allowed to pass in None, Default False |
validators | The verifier used by this field |
error_messages | A dictionary containing error numbers and information |
label | be used for HTML Exhibition API When the page is , The name of the field displayed |
help_text | be used for HTML Exhibition API When the page is , Field help prompt information displayed |
3、 ... and 、 Deserialization :JSON Convert to model process ( Just pass it on data)
Deserialization : Get data from the front end 、 Serializer's
data
、 Calling the serializeris_valid()
Method is called verification 、 Calling the serializersave()
Method 、 Finally, serialize
- Get the... Passed in from the front end
json
Dictionary data - Create a serializer , For serializer
data
Parameter transfer ( Parameters need to be transferred with keyword parameters ) - Calling the serializer
is_valid(raise_excption=True)
check , If the verification is wrong, an error message will be thrown automatically - Calling the serializer
save()
Method , callsave
It will determine whether the initial serializer has passedinstance
- if Into
instance
It also introduceddata
, So called save What the method actually calls is... In the serializerupdate
Method , If onlydata
Is to call... In the serializercreate
Method - Deserialization will automatically complete serialization at last , through
ser.data
obtain
3.1 Deserialization verification method
3.1.1 Field option parameters
Set parameters in serialization , Such as length
title = serializers.CharField(max_length=32)
3.1.2 Custom method verification
There are three forms of custom methods , Can be used in combination :
- validate( Joint verification , Custom verification of all fields , Defined method function name , In the serialization class )
- validate_ Field name ( Local verification , Verify the data of the field name , Defined method function name , In the serialization class , Generally, joint verification is used to do local verification )
- validators( Field parameters , The defined method function name can be arbitrary , Outside the serialization class , Usage method By entering validators=[method1,method2])
from rest_framework import serializers
def about_publish(value):
if 'django' not in value.lower():
raise serializers.ValidationError(" Does not contain Django!")
return value
class PublishSerializer(serializers.Serializer):
publish = serializers.CharField(max_length=32,validators=[about_publish])
datetime = serializers.SerializerMethodField(read_only=True)
def get_datetime(self,obj):
# Extra parameters
import datetime
return f'{
datetime.datetime.now()}'
def validate(self, attrs):
if ' Press. ' not in attrs['publish'].lower():
raise serializers.ValidationError(" Not including publishing house !")
return attrs
3.2 Save the data
After verifying the data successfully , Use serializer to complete data deserialization , Turn data into model class objects , By implementing
create()
andupdate()
Two ways to achieve . If you create a serializer object , No deliveryinstance
example , Callsave()
Method time ,create()
Called ; If it's deliveredinstance
example , Callsave()
Method time ,update()
Called .
from rest_framework import serializers
def about_publish(value):
if 'django' not in value.lower():
raise serializers.ValidationError(" Does not contain Django!")
return value
class PublishSerializer(serializers.Serializer):
publish = serializers.CharField(max_length=32,validators=[about_publish])
datetime = serializers.SerializerMethodField(read_only=True)
def get_datetime(self,obj):
# Extra parameters
import datetime
return f'{
datetime.datetime.now()}'
def validate(self, attrs):
if ' Press. ' not in attrs['publish'].lower():
raise serializers.ValidationError(" Not including publishing house !")
return attrs
def create(self, validated_data):
# The new data
publish = Publish.objects.create(**validated_data)
return publish
def update(self, instance, validated_data):
# Update data , there instance It's the incoming install = Model .objects.get(id=1) (obj Model object )
instance.publish = validated_data["publish"]
instance.save()
return instance
3.2.1 The new data call create
In [11]: from book.serializers import PublishSerializer
In [12]: from book.models import Publish
In [13]: data = {
...: "publish":"Django Press. DRF"
...: }
In [14]: ser = PublishSerializer(data=data)
In [15]: ser.is_valid(raise_exception=True)
Out[15]: True
In [16]: ser.save()
Out[16]: <Publish: Django Press. DRF>
In [17]: ser.data
Out[17]: {
'publish': 'Django Press. DRF', 'datetime': '2021-10-09 10:03:09.150345'}
In [18]: [i.publish for i in Publish.objects.all())
File "<ipython-input-18-24069f24a3bb>", line 1
[i.publish for i in Publish.objects.all())
^
SyntaxError: closing parenthesis ')' does not match opening parenthesis '['
# You can see the success of the new
In [19]: [i.publish for i in Publish.objects.all()]
Out[19]: ['CQJTU', 'Djangosa Press. ', 'Djangosa Press. ', 'Django Press. DRF']
3.2.2 Update data call update
In [1]: from book.models import Publish
# Before the change
In [2]: [i.publish for i in Publish.objects.all()]
Out[2]: ['CQJTU', 'Djangosa Press. ', 'Djangosa Press. ', 'Django Press. DRF']
# Specify which
In [3]: pub = Publish.objects.get(pk=1)
In [4]: from book.serializers import PublishSerializer
In [5]: ser = PublishSerializer(instance=pub,data={
'publish':'CQJTU Press. Django'})
In [6]: ser.is_valid()
Out[6]: True
In [7]: ser.save()
Out[7]: <Publish: CQJTU Press. Django>
In [8]: ser.data
Out[8]: {
'publish': 'CQJTU Press. Django', 'datetime': '2021-10-09 10:10:28.303865'}
# After modification
In [9]: [i.publish for i in Publish.objects.all()]
Out[9]: ['CQJTU Press. Django', 'Djangosa Press. ', 'Djangosa Press. ', 'Django Press. DRF']
3.3 Additional notes
- 1) The serializer is being save() When saving , Additional data can be transferred , The data can be found in create() and update() Medium validated_data Parameter to
# request.user yes django Record the model object of the currently logged in user
serializer.save(owner=request.user)
- 2) The default serializer must pass all required Field of , Otherwise, a validation exception will be thrown . But we can use partial Parameter to allow some fields to be updated details
# Update `comment` with partial data
serializer = CommentSerializer(comment, data={'content': u'foo bar'}, partial=True)
Four 、 Model serializer class instructions
ModelSerializer
Inherited fromSerializer
- It can automatically generate the fields in the serializer according to the model
- It realizes
create
andupdate
Method - But we can also be as general
Serializer
To rewrite some custom methods to verify
class BookModelSerializer(serializers.ModelSerializer):
ext = serializers.CharField()
class Meta:
''' Specify that the model needs to be serialized '''
model = Book
''' Specify the fields in the model that need to be serialized New fields need to be added, followed by '''
# All fields in the model
# fields = '__all__'
# Some fields in the model
# fields = ['title','created_time','ext']
''' Exclude the fields that need to be serialized in the model There is no need to add '''
# except title Don't need everything else ( Including new fields )
exclude = ['title',]
''' Modify the parameters in the field '''
# When the generated automatic parameters do not meet the requirements , Of course, you can also customize the method to verify , Methods with Serializer
# Not modifiable here read_only = True
extra_kwargs = {
'title':{
'write_only':True,
'max_length':32,
},
'created_time':{
'format':"%Y-%m-%d %H:%M:%S"
}
}
''' Specify which fields are serialized only '''
read_only_fields = ["created_time"]
# Extra parameters
def get_ext(self,obj):
return f' The other parameters :{
obj.title}'
# Custom method verification
def validate(self, attrs):
if 'django' not in attrs["title"].lower():
raise serializers.ValidationError(" The title of the book does not contain Django")
return attrs
Serializer
Not only can it be used to verify data storage , It can also be used to store in a data free model, such asredis
Etc , andModelSerializer
Only applicable when there is a data model .
边栏推荐
- Interview question: general layout and wiring principles of high-speed PCB
- H3C vxlan configuration
- JVM 内存结构 详细学习笔记(一)
- How long does the PMP usually need to prepare for the exam in advance?
- Selenium mouse sliding operation event
- What are the conditions for applying for NPDP?
- Output a spiral matrix C language
- Digital triangle model acwing 275 Pass a note
- Skill review of test engineer before interview
- Summary of PMP learning materials
猜你喜欢
随机推荐
Vagrant failed to mount directory mount: unknown filesystem type 'vboxsf'
JVM 垃圾回收 详细学习笔记(二)
C语言指针(特别篇)
徽商期货公司评级是多少?开户安全吗?我想开户,可以吗?
Reading notes of pyramid principle
LeetCode 715. Range module
Pytest+request+allure+excel interface automatic construction from 0 to 1 [five nails / flying Book notice]
go mod module declares its path as: gtihub. com/xxx-xx but was required as:xx-xx
模拟卷Leetcode【普通】1706. 球会落何处
Confitest of fixture py
Interview question: general layout and wiring principles of high-speed PCB
Simulation volume leetcode [general] 1557 The minimum number of points that can reach all points
What is the rating of Huishang futures company? Is it safe to open an account? I want to open an account, OK?
Implement custom memory allocator
面试题:高速PCB一般布局、布线原则
2022-06-30 Unity核心8——模型导入
channel. Detailed explanation of queuedeclare parameters
External interrupt to realize key experiment
The essence of high availability
数据在内存中的存储