ListModelSerializer模块
自定义反序列化字段
Copygit
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
二、模型类中自定义序列化深度
Copy数据库
class Book(BaseModel):
# ...
@property
def publish_detail(self):
from . import serializers
data = serializers.PublishModelSerializer(self.publish).data
return data
三、接口操做总结
Copydjango
路由层:api/url.py
Copy
from django.conf.urls import url
from . import views
urlpatterns = [
# ...
url(r'^v3/books/$', views.BookV3APIView.as_view()),
url(r'^v3/books/(?P
]
模型层:api/models.py
Copy
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,
)app
@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 # 联合惟一 # unique_together = ('name', 'publish') def __str__(self): return self.name
class Publish(BaseModel):
name = models.CharField(max_length=64)
address = models.CharField(max_length=64)post
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()ui
@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)url
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
Copycode
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): # type: int, models.Book
# 单个对象数据更新 - 一个个属性更新值
for attr, value in validated_data[index].items():
# 对象有更新数据字典的key对应的属性,才完成该属性的值更新
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
Copy
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): # 单增 /books/ data {} # 群增 /books/ data [{}, ..., {}] 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): # 单改 /books/(pk)/ data {"name": "new_name", ...} # 群改 /books/ data [{"pk": 1, "name": "new_name", ...}, ...,{"pk": n, "name": "new_name", ...}] # 结果: # pks = [1, ..., n] => book_query => instance # data = [{"name": "new_name", ...}, ..., {"name": "new_name", ...}] => data # 数据预处理 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): # 单删 /books/(pk)/ # 群删 /books/ 数据包携带 pks => request.data 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): # 操做的记录大于0就记录删除成功 return APIResponse(1, '删除失败') return APIResponse(0, '删除成功')