当前位置:网站首页>DRF - deserialization of serializer, fields and parameters, local and global hooks, use of modelserializer
DRF - deserialization of serializer, fields and parameters, local and global hooks, use of modelserializer
2022-07-29 00:47:00 【There is a car on the hill】
List of articles
List of articles
One 、Serializer Deserialization of
Use serializer Serializer error , Deserialization is generally aimed at update and create, Therefore, if there is a corresponding table primary key, it is best to set it read_only by True
When there is no external relationship in the table, you can use serializer perhaps ModelSerializer
Show here Serializer Usage mode
Table relations :
class Book(models.Model):
bname = models.CharField(max_length=20, verbose_name=' Book name ')
price = models.DecimalField(max_digits=5, decimal_places=2, verbose_name=' Book unit price ')
def __str__(self):
return self.bname
Corresponding Serializer Serializer
Aim at Serializer Creation and update methods need to be rewritten , Delete 、 Inquire about 、 The query of a single need to be completed in the view class
class BookSerializer(serializers.Serializer):
bname = serializers.CharField(max_length=20)
price = serializers.DecimalField(max_digits=5, decimal_places=2)
def update(self, instance, validated_data):
instance.bname = validated_data.get('bname')
instance.price = validated_data.get('price')
instance.save()
return instance
def create(self, validated_data):
book_obj = Book.objects.create(**validated_data)
return book_obj
Corresponding to the view class
class BookApiView(views.APIView):
def get(self,request):
dict = {
{
'code':200, 'msg':' Query successful '}}
if not request.query_params:
books = Book.objects.all()
dict['msg'] = ' Query all books successfully '
else :
books = Book.objects.filter(pk=request.query_params.get('id'))
dict['msg'] = ' Query a book successfully '
bookSerializer = BookSerializer(instance=books, many=True)
dict['data'] = bookSerializer.data
return Response(dict)
def delete(self,request):
dict = {
'code':200}
pk = request.data.get('id')
if pk:
book_obj = Book.objects.filter(pk=pk)
if book_obj:
book_obj.delete()
dict['msg'] = ' Delete successful '
dict['data'] = ''
else :
dict['code'] = 10003
dict['msg'] = ' The book does not exist , Cannot delete '
else:
dict['code'] = 10004
dict['msg'] = ' Please specify books id'
return Response(dict)
def put(self,request):
dict = {
'code': 200}
book_obj = Book.objects.filter(pk=request.data.get('id')).first()
if book_obj:
bookSerializer = BookSerializer(instance=book_obj, data=request.data)
if bookSerializer.is_valid():
bookSerializer.save()
dict['msg'] = ' Modification successful '
dict['data'] = bookSerializer.data
else:
dict['code'] = 10001
dict['msg'] = ' Modification failed , Data failed validation '
dict['errors'] = bookSerializer.errors
else:
dict['code'] = 10002
dict['msg'] = ' The book does not exist '
dict['errors'] = ' Cannot find the corresponding book id'
return Response(dict)
def post(self,request):
print(request.FILES)
dict = {
'code': 200}
bookSerializer = BookSerializer(data=request.data)
if bookSerializer.is_valid():
bookSerializer.save()
dict['msg'] = ' Create success '
dict['data'] = bookSerializer.data
else:
dict['code'] = 10005
dict['msg'] = ' Data validation failed '
dict['errors'] = bookSerializer.errors
return Response(dict)
Two 、Serializer Fields and parameters
Common fields and models Almost the same
Common parameters :
read_only:True If it is not set, it defaults to False The function is to generate the field data only during serialization
write_only:True If it is not set, it defaults to False The function is to only need the field data when deserializing
error_messages Set the error message that the field fails the inspection
depth Join table query depth
3、 ... and 、Serializer Local and global hooks
Local hooks are rewritten validate_ Field name function
Use when you need to throw an error ValidationError
When it passes the verification, the corresponding field is returned
def validate_pname(self, pname):
if re.findall(' JD.COM ', pname):
raise ValidationError(' The name of the publishing house cannot contain JD ')
else:
return pname
The global hook is rewritten validate function In the global hook attrs Is corresponding to all fields in the serializer
Use when you need to throw an error ValidationError
When it passes the verification, the corresponding attrs
def validate(self, attrs):
if re.findall(' Japan ', attrs.get('address')):
raise ValidationError(' The address of the publishing house cannot be in Japan ')
return attrs
Four 、 Serialization class ModelSerializer Use
modelSerializer yes model And serializer The combination of , stay ModelSerializer We only need to configure the corresponding fields and their parameters , You don't have to rewrite it update and create Method ,ModeSerializer It will automatically complete the operation of adding, deleting, modifying and querying .
models.py
class Book(models.Model):
bid = models.AutoField(primary_key=True)
name = models.CharField(max_length=32)
price = models.DecimalField(max_digits=5, decimal_places=2)
publish = models.ForeignKey(to='Publish', on_delete=models.CASCADE)
authors = models.ManyToManyField(to='Author')
def __str__(self):
return self.name
ModelSerializer Serializer
class BookSerializer(serializers.ModelSerializer):
class Meta:
model = models.Book # Set here ModelSerializer Associated table
# Here are two ways to set
fields = '__all__' # Method 1 Use __all__ Will automatically match models All fields in
fields = ['bid', 'name', 'price', 'publish', 'authors', 'publish_read', 'authors_read'] # Method 2 Use the form of list to fill in the corresponding fields
extra_kwargs = {
'bid': {
'read_only':True},
'publish': {
'write_only': True},
'authors': {
'write_only': True},
} # Perform Serializer Set parameters , At this time Serializer Field name and models In the agreement
There are three ways to deserialize foreign key fields ( Serialization by ModelSerializer Done automatically )
The first one is , Build virtual fields to provide query results of foreign key fields for deserialization ( This method is not recommended )
class BookSerializer(serializers.ModelSerializer):
class Meta:
model = models.Book # Set here ModelSerializer Associated table
# Here are two ways to set
fields = '__all__' # Method 1 Use __all__ Will automatically match models All fields in , Then create a new virtual field
fields = ['bid', 'name', 'price', 'publish', 'authors', 'publish_read', 'authors_read'] # Method 2 Use the form of list to fill in the corresponding fields, including virtual fields , Then reset the virtual field
# fields Choose one
extra_kwargs = {
'bid': {
'read_only':True}, # When deserializing, the primary key is usually set read_only
} # Perform Serializer Set parameters , At this time Serializer Field name and models In the agreement
# Create virtual fields here , Note that the virtual field is class BookSerializer Properties of ( Note that the indentation )
publish_read = serializers.SerializerMethodField(read_only=True) # The virtual field name can be set at will , Don't forget to set up read_only
authors_read = serializers.SerializerMethodField(read_only=True)
# After setting the virtual field, you need to generate the corresponding virtual field value method
def get_publish_read(self, book): # The method name here must be get_ Virtual field name , Parameters self by serializer class ,book You can set the name freely. This parameter is the corresponding table object
return book.publish.name # The return value is obtained according to the foreign key relationship, preferably query_set, One to many needs to return query_set, One on one, you have to return query_set The difference is one-on-one query_set There is only one dictionary in
# For many to many fields, cyclic processing is required
def get_authors_read(self, book):# Because of the many to many relationship at this time book For one query_set It contains multiple table objects
authors_list = []
for author in book.authors.all():
authors_list.append({
'aid':author.pk, 'name':author.name, 'age':author.age, 'address':author.author_detail.address})
return authors_list
The second kind of plug-in virtual field setting
ModelSerializer Serializer :
class BookSerializer(serializers.ModelSerializer):
class Meta:
model = models.Book
fields = ['bid', 'name', 'price', 'publish', 'authors', 'publish_read', 'authors_read'] # Here, you need to correspond the method name to the virtual field name , Not available __all__
extra_kwargs = {
'bid': {
'read_only':True},
'publish': {
'write_only': True},
'authors': {
'write_only': True},
}
models Model :
class Book(models.Model):
bid = models.AutoField(primary_key=True)
name = models.CharField(max_length=32)
price = models.DecimalField(max_digits=5, decimal_places=2)
publish = models.ForeignKey(to='Publish', on_delete=models.CASCADE)
authors = models.ManyToManyField(to='Author')
def __str__(self):
return self.name
@property # When fields The first one is to add this decorator The decorator is used to change class methods into class attributes
def publish_read(self):
return {
'name':self.publish.name,'email':self.publish.email}
@property
def authors_read(self):
authors_read=[]
for author in self.authors.all():
authors_read.append({
'name':author.name,'address':author.author_detail.address})
return authors_read
The third way is to set the depth of the table
Join table query depth :
It is the setting of the number of times to connect the table
for example :
The author table and the publisher table are one to many , From the author table, you can connect the table to query the corresponding press information Now the depth is 1
The publisher table and the book table are one to many , Query the corresponding books from the press table , Now the depth is 2
… Follow this up
class BookSerializer(serializers.ModelSerializer):
class Meta:
model = models.Book
fields = ['bid', 'name', 'price', 'publish', 'authors']
depth = 1 # Official advice is not to exceed 10, In fact, it's better not to exceed 3
extra_kwargs = {
'bid': {
'read_only':True},
}
边栏推荐
- Application and principle of distributed current limiting redistribution rratelimiter
- Requestvideoframecallback() simple instance
- 17. Design of machine learning system
- 数仓搭建——DWT层
- 【飞控开发基础教程8】疯壳·开源编队无人机-I2C(激光测距)
- 110 MySQL interview questions and answers (continuously updated)
- redis版本怎么查看(查看redis进程)
- 【esn】 学习回声状态网络
- 乱打日志的男孩运气怎么样我不知道,加班肯定很多!
- Locally connect to redis on Windows Server
猜你喜欢

“吃货联盟定餐系统”

Requestvideoframecallback() simple instance

PTA (daily question) 7-70 diamond

Some operations of Ubuntu remote server configuration database (unable to locate package MySQL server, steps of installing mysql, unable to enter password when logging in MySQL)

第二轮1000个Okaleido Tiger,再次登录Binance NFT 1小时售罄

Install mysql5.7 under Linux, super detailed complete tutorial, and cloud MySQL connection

PTA (daily question) 7-69 narcissus number

Upload Excel files with El upload and download the returned files

还在写大量 if 来判断?一个规则执行器干掉项目中所有的 if 判断...

MySQL 分库分表及其平滑扩容方案
随机推荐
第二轮1000个Okaleido Tiger,再次登录Binance NFT 1小时售罄
I don't know how lucky the boy who randomly typed the log is. There must be a lot of overtime!
zabbix部署及监控
SAP vl02n delivery note posting function WS_ DELIVERY_ UPDATE
Some operations of Ubuntu remote server configuration database (unable to locate package MySQL server, steps of installing mysql, unable to enter password when logging in MySQL)
还在写大量 if 来判断?一个规则执行器干掉项目中所有的 if 判断...
【esn】 学习回声状态网络
2022dasctfjuly empowerment competition (reappearance)
[ESN] learning echo state network
Common sparse basis and matlab code for compressed sensing
About 1931cie -- conversion of XYZ color coordinate graph to RGB color coordinate relationship
Application and principle of distributed current limiting redistribution rratelimiter
Router view cannot be rendered (a very low-level error)
Summary: the difference between pod and container
Teach you how to install latex (nanny level tutorial)
I don't recommend you use Select*
Table custom style row class name in elemenui
redis版本怎么查看(查看redis进程)
PTA (daily question) 7-71 character trapezoid
PTA (daily question) 7-77 encryption