当前位置:网站首页>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},
}
边栏推荐
- Introduction of shortest path tree (SPT) and matlab code
- ORACLE not available如何解决
- Tips for API interface optimization
- [small bug diary] Navicat failed to connect to MySQL | MySQL service disappeared | mysqld installation failed (this application cannot run on your computer)
- Dynamic programming problem (2)
- NFTScan 与 NFTPlay 在 NFT 数据领域达成战略合作
- Basic knowledge of PHP language (super detailed)
- 【网络安全】通过iptables和ipset完成服务器防火墙黑名单和白名单功能
- What does the expression > > 0 in JS mean
- Installation and use of pnpm
猜你喜欢

Html+css+php+mysql realize registration + login + change password (with complete code)

Router view cannot be rendered (a very low-level error)

Dynamic programming problem (VIII)

分布式限流 redission RRateLimiter 的使用及原理

NPM run serve stuck at 40%

Dynamic programming problem (VII)

Alibaba code index technology practice: provide reading experience of local IDE for code review

Shell programming specifications and variables

“吃货联盟定餐系统”

Requestvideoframecallback() simple instance
随机推荐
SAP vl02n delivery note posting function WS_ DELIVERY_ UPDATE
Software designer afternoon question
分布式限流 redission RRateLimiter 的使用及原理
Minimum dominating set (MDS) and its matlab code
1331. Array sequence number conversion: simple simulation question
I don't recommend you use Select*
第二轮1000个Okaleido Tiger,再次登录Binance NFT 1小时售罄
Outlier detection and open set identification (1)
Shell编程规范与变量
Oracle实例无法启动的问题如何解决
Longest ascending subsequence
异步模式之工作线程
Alibaba code index technology practice: provide reading experience of local IDE for code review
andriod6.0低功耗模式(关闭wifi、蓝牙、gps、屏幕亮度等)
mysql时间按小时格式化_mysql时间格式化,按时间段查询的MySQL语句[通俗易懂]
[micro services ~nacos] Nacos service providers and service consumers
ORACLE not available如何解决
【愚公系列】2022年07月 Go教学课程 020-Go容器之数组
ZABBIX deployment and monitoring
Flask sends verification code in combination with Ronglian cloud