zoukankan      html  css  js  c++  java
  • 【1120 | Day63】ListSerializer组件

    一、自定义反序列化字段

    一些只参与反序列化的字段,但是不与数据库关联的,在序列化类中规定并在校验字段时,从校验的参数字典中剔除

    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
    

    二、模型类中自定义序列化深度

    model类中自定义插拔的外键序列化字段,可以采用外键关联表的序列化类来完成深度查询

    class Book(BaseModel):
    
         # ...
         
         @property
         def publish_detail(self):
             from . import serializers
             data = serializers.PublishModelSerializer(self.publish).data
             return data
    

    三、接口操作总结

    单查群查、单删群删、单增群增、单改群改

    路由层: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

    # 修改部分:取消book类 name 与 publish 联合唯一,
    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
             # 联合唯一
             # 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)
    
         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

    # 群增与群改反序列化实现
    # 1)ModelSerializer默认不通过群改功能,需要在Meta中设置 list_serializer_class
    # 2)自定义ListSerializer子类,重写update方法,将子类绑定给 list_serializer_class
    # 3)重写update方法中通过 代表要更新的对象们instance 及 提供的更新数据们validated_data
    # 得到 更新后的对象们instance 返回
    
    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





  • 相关阅读:
    WPF Web Application 客户端下载目录及有趣的搜索问题
    判断表是否存在
    C#获取存储过程返回值和输出参数值
    模态对话框刷新问题
    sql Server 导出数据到脚本
    使用.NET 2.0中的秒表-Stopwatch类进行速度测试 (转一个程序员的自省)
    使用Redirect打开新窗口
    弹出层
    windows7安装配置IIS7.5过程图解
    控制文本框输入
  • 原文地址:https://www.cnblogs.com/fxyadela/p/11901398.html
Copyright © 2011-2022 走看看