ListModelSerializer模块
自定义反序列化字段
class PublishModelSerializer (serializers.ModelSerializer):
re_name = serializers.CharField(write_only=True )
class Meta :
model = models.Publish
fields = ('name' , 're_name' , 'address' )
def validate (self, attrs ):
name = attrs.get('name' )
re_name = attrs.pop('re_name' )
if name != re_name:
raise serializers.ValidationError({'re_name' : '确认名字有误' })
return attrs
2、模型类中自定义序列化深度
class Book (BaseModel ):
@property
def publish_detail (self ):
from . import serializers
data = serializers.PublishModelSerializer(self.publish).data
return data
3、接口操作总结
路由层:api/url.py
from django.conf.urls import url
from . import views
urlpatterns = [
url(r'^v3/books/$' , views.BookV3APIView.as_view()),
url(r'^v3/books/(?P<pk>.*)/$' , views.BookV3APIView.as_view()),
]
模型层:api/models.py
from django.db import models
from utils.model import BaseModel
class Book (BaseModel ):
name = models.CharField(max_length=64 )
price = models.DecimalField(max_digits=5 , decimal_places=2 )
img = models.ImageField(upload_to='img' , default='img/default.png' )
publish = models.ForeignKey(to='Publish' , null=True ,
related_name='books' ,
db_constraint=False ,
on_delete=models.DO_NOTHING,
)
authors = models.ManyToManyField(to='Author' , null=True ,
related_name='books' ,
db_constraint=False ,
)
@property
def publish_name (self ):
return self.publish.name
@property
def authors_info (self ):
author_list = []
for author in self.authors.all ():
author_list.append({
'name' : author.name,
'age' : author.age,
'mobile' : author.detail.mobile
})
return author_list
@property
def publish_bac (self ):
from . import serializers
data = serializers.PublishModelSerializer(self.publish).data
return data
class Meta :
db_table = 'old_boy_book'
verbose_name = '书籍'
verbose_name_plural = verbose_name
def __str__ (self ):
return self.name
class Publish (BaseModel ):
name = models.CharField(max_length=64 )
address = models.CharField(max_length=64 )
class Meta :
db_table = 'old_boy_publish'
verbose_name = '出版社'
verbose_name_plural = verbose_name
def __str__ (self ):
return self.name
class Author (BaseModel ):
name = models.CharField(max_length=64 )
age = models.IntegerField()
@property
def mobile (self ):
return self.detail.mobile
class Meta :
db_table = 'old_boy_author'
verbose_name = '作者'
verbose_name_plural = verbose_name
def __str__ (self ):
return self.name
class AuthorDetail (BaseModel ):
mobile = models.CharField(max_length=11 )
author = models.OneToOneField(to='Author' , null=True ,
related_name='detail' ,
db_constraint=False ,
on_delete=models.CASCADE
)
class Meta :
db_table = 'old_boy_author_detail'
verbose_name = '作者详情'
verbose_name_plural = verbose_name
def __str__ (self ):
return '%s的详情' % self.author.name
序列化层:api/serializers.py
class BookV3ListSerializer (serializers.ListSerializer):
def update (self, instance, validated_data ):
'''
:param instance: [book_obj1, ..., book_obj2]
:param validated_data: [{更新数据的字段}, ..., {更新数据的字段}]
:return: [book_new_obj1, ..., book_new_obj2]
'''
for index, obj in enumerate (instance):
for attr, value in validated_data[index].items():
if hasattr (obj, attr):
setattr (obj, attr, value)
obj.save()
return instance
class BookV3ModelSerializer (serializers.ModelSerializer):
class Meta :
model = models.Book
fields = ('name' , 'price' , 'publish' , 'authors' , 'img' , 'publish_name' , 'authors_info' )
list_serializer_class = BookV3ListSerializer
extra_kwargs = {
'publish' : {
'required' : True ,
'write_only' : True
},
'authors' : {
'required' : True ,
'write_only' : True
},
'img' : {
'read_only' : True
}
}
def validate_name (self, value ):
if 'sb' in value:
raise serializers.ValidationError('书名有敏感词汇' )
return value
def validate (self, attrs ):
name = attrs.get('name' )
publish = attrs.get('publish' )
if models.Book.objects.filter (name=name, publish=publish):
raise serializers.ValidationError({'book' : '书籍以存在' })
return attrs
视图层:api/views.py
class BookV3APIView (APIView ):
def get (self, request, *args, **kwargs ):
pk = kwargs.get('pk' )
if pk:
book_obj = models.Book.objects.filter (is_delete=False , pk=pk).first()
if not book_obj:
return APIResponse(1 , 'pk error' )
book_ser = serializers.BookV3ModelSerializer(book_obj)
return APIResponse(0 , 'ok' , results=book_ser.data)
book_query = models.Book.objects.filter (is_delete=False ).all ().order_by('-id' )
book_ser = serializers.BookV3ModelSerializer(book_query, many=True )
return APIResponse(0 , 'ok' , results=book_ser.data)
def post (self, request, *args, **kwargs ):
request_data = request.data
if isinstance (request_data, dict ):
data = [request_data, ]
elif isinstance (request_data, list ):
data = request_data
else :
return APIResponse(1 , '数据格式有误' )
book_ser = serializers.BookV3ModelSerializer(data=data, many=True )
if book_ser.is_valid():
book_obj_list = book_ser.save()
return APIResponse(0 , 'ok' ,
results=serializers.BookV3ModelSerializer(book_obj_list, many=True ).data
)
else :
return APIResponse(1 , '添加失败' , results=book_ser.errors)
"""
1)先确定要更新的对象 主键们 与 数据们
2)通过校验数据库剔除 已删除的对象 与 不存在的对象
主键们 => 剔除过程 => 可以修改的对象们
数据们 => 剔除过程 => 可以修改的对象们对应的数据们
3)反序列化及校验过程
通过 => save() 完成更新
失败 => ser_obj.errors 返回
"""
def patch (self, request, *args, **kwargs ):
pk = kwargs.get('pk' )
request_data = request.data
if pk:
if not isinstance (request_data, dict ):
return APIResponse(1 , '单改数据有误' )
pks = [pk, ]
data = [request_data, ]
elif isinstance (request_data, list ):
try :
pks = []
for dic in request_data:
pks.append(dic.pop('pk' ))
data = request_data
except :
return APIResponse(1 , '群改数据有误' )
else :
return APIResponse(1 , '数据格式有误' )
book_query = []
filter_data = []
for index, pk in enumerate (pks):
book_obj = models.Book.objects.filter (is_delete=False , pk=pk).first()
if book_obj:
book_query.append(book_obj)
filter_data.append(data[index])
book_ser = serializers.BookV3ModelSerializer(instance=book_query, data=filter_data, many=True , partial=True )
if book_ser.is_valid():
book_obj_list = book_ser.save()
return APIResponse(1 , 'ok' ,
results=serializers.BookV3ModelSerializer(book_obj_list, many=True ).data
)
else :
return APIResponse(1 , '更新失败' , results=book_ser.errors)
def delete (self, request, *args, **kwargs ):
pk = kwargs.get('pk' )
if pk:
pks = [pk]
else :
pks = request.data.get('pks' )
if not pks:
return APIResponse(1 , '删除失败' )
book_query = models.Book.objects.filter (is_delete=False , pk__in=pks)
if not book_query.update(is_delete=True ):
return APIResponse(1 , '删除失败' )
return APIResponse(0 , '删除成功' )
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!