DRF实战开发技巧(序列化器的一些操作)

一:Serializer使用中的一些理解

1)对于增加数据需要实现create方法,对于修改数据需要实现update方法
.
2)所有要经过序列化的字段必须要写出,并指定是否只序列化read_only或只做反序列化write_only指定为True,对于不需要必传的字段指定required=False.
.
3)通过实现 validate_字段名(self, value)进行字段验证,通过def validate(self, attrs):进行组合验证,所有数据都在attrs中,验证完要进行返回return attrs。验证会在视图层调用serializer.is_valid(raise_exception=True)时触发。

二:ModelSerializer使用中的一些理解

1)需要一个元类 class Meta: 中去配置要序列化哪些字段,以及对这些字段的一些限制
.
2)如:
model指定数据库模型,
fields指定映射哪些字段,
exclide指定的字段为:(除了这些字段其他的都映射),
read_only_fields指定的为只做序列化的,
对于特定的字段进行约束可以通过extra_kwargs
例如:
extra_kwargs= { # 修改参数选项
‘UPassword’: {‘write_only’:True},
}
等等,就写这些,有问题再csdn

三: 对于序列化关系,自己解决过的一些问题

  1. )通过 serializers.RelatedField 实现 输出主表的数据时,**指定一个字段输出 (外键是这个主表的表的字段,这里序列化器可以是继承ModelSerializer,也可以是继承Serializer。ModelSerializer与Serializer也是serializers.ModelSerializer与serializers.Serializer。

    a) 首先我们要看models模型的代码(特别注意一下外键的参数设置)如下:

    这里特别要注意 我们指定的的 related_name=‘一个名字’,这里指定的
    名字,在主表进行序列化输出是,可以增加一个相同名字的字段进行其对应
    外键所在表的字段输出

    # 一个主表用户表
    class Users(models.Model):
    	‘’‘各种字段’‘’
    	...
    	class Meta:
    		...
    # 一个带外键的表,追
    class Equip(models.Model):
    	...
    	# 这里特别要注意 我们指定的的 related_name='一个名字',这里指定的
    	# 名字,在主表进行序列化输出是,可以增加一个相同名字的字段进行其对应
    	# 外键所在表的字段输出
    	Euid = models.ForeignKey(Users,related_name='Equips',
    	    						on_delete=models.CASCADE)		
    	...
    	
    	class Meta:
    		...
    

    b) 我们再看序列化器的代码:

    指定一个序列化外键所在表字段的类

    我们需要一个继承serializers.RelatedField的类,然后实现 to_representation方法,在这个方法里返回我们所需要的外键所在表的字段,value参数就代表了外键表中的一个模型

    # 用户装备序列化 一对多数据输出
    class EquipsField(serializers.RelatedField):
    	def to_representation(self, value):
       		return '%s' % value.EName
    

    主键的表进行序列化输出时,带上外键所在表的某个字段:

    重点我们看这里,EquipsField是我们自定一个序列化器类,
    Equips 是我们在models模型时就限定的一个字段名字,
    这样我们就可以通过这个字段找到对应 外键所在的表了

    class UserRegSerializer(serializers.Serializer):
    	...
    	# 重点我们看这里,EquipsField是我们自定一个序列化器类,
    	#Equips 是我们在models模型时就限定的一个字段名字,
    	#这样我们就可以通过这个字段找到对应 外键所在的表了
    	Equips = EquipsField(many=True, read_only=True)
    	...
    
    
  2. 数据库中不存在的坐标,临时的进行序列化输出 serializers.SerializerMethodField

    通过serializers.SerializerMethodField 实现临时的字段,需要赋值的字段名下面会用
    这个字段的值需要实现 def get_字段名(self,obj) 这里的obj 就是当前的模型对象

    代码:

    class UserLoginSerializer(serializers.ModelSerializer):
    	...
    	# 通过serializers.SerializerMethodField 实现临时的字段,需要赋值的字段名下面会用
    	# 这个字段的值需要实现 def get_字段名(self,obj)  这里的obj 就是当前的模型对象
    	token = serializers.SerializerMethodField(label='token', read_only=True)
    	...
    	class Mate:
    		...
    		
    	def get_token(self, obj):
      		jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
        	jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER
        	payload = jwt_payload_handler(obj)
        	token = jwt_encode_handler(payload)
        return token
    
  3. 像serializers.RelatedField所创建的类只可以做主键表序列化输出时使用,当要通过主表进行反序列化的时候,向外键所在的表添加数据可以通过 一个字段实现外键所在序列化类的对象的形式去搞定

    外键需要一个序列化器,在主键表的序列化器中有一个字段实现了外键的序列化器对象,实现create方法在,主键表的模型对象中提取出外键的数据,通过外键的模型调用create方法进行保存外键的数据!!!!!就是这样!!!!yes

    代码:

    # 外键所在表的  序列化器
    class PhotoGallerySerializer(serializers.Serializer):
    	# Gid 是本表的一个外键,对应的主键表为 Group
        Gid = serializers.PrimaryKeyRelatedField(queryset=Group.objects.all(),error_messages={"error":"无此任务"})
        images = serializers.ImageField(label='人脸图片')
        Url = serializers.CharField(max_length=100, label='人脸图片链接', required=False)
    
    	 def create(self, validated_data):
         	 image = PhotoGallery.objects.create(**validated_data)
        	 urlFormat(image, image.images)
        	 return image
    
    # 主键所在表的序列化器
    class GroupSerializer(serializers.ModelSerializer):
    	...
    	# 我们通过外键序列化器  实现一个字段,因为我们是ModelSerializer
    	# 虽然已经集成了create方法,但是,由于我们要向外键表存数据,要重写create函数
    	# 而外键的数据也是在主键表这里反序列化时带的,所以肯定要走create函数
    	# 所以我们对应 Urls这个外键表的数据进行存储时,要在Group的create函数里实现,如下面
    	Urls = PhotoGallerySerializer(many=True, required=False)
    	
    	# 由于我们要传图片, 所以需要一个存储图片路径的字段,后期通过
    	# 取出这个字段拼接绝对路径,进行传输七牛云生成外链图
    	GImage = serializers.ImageField(label='人脸图片')
    	
    	
    	def create(self, validated_data):
    		# Group模型的数据
        	group = Group.objects.create(**validated_data)  
        	# 我们需要其中的图片路径,因为外键表是一个图片库,通过编写的format
        	# 对接七牛云返回外链
        	urls = urlformat(group.GImage) 
        	# 在创建群组的时候,要向其外键的表保存图片
        	photoValidated_data = {
            	'images': group.GImage,
            	'Url': urls,
            	'Gid_id': group.id
        	}
        	# 通过 create保存外键表的数据
        	PhotoGallery.objects.create(**photoValidated_data)
        	return group
    	
    	...
    
    

    *) 在这里补充一下图片上传,的models代码如下

    图片的字段或者文件的字段, 通过 upload_to 指定自己写好的fromat函数,返回的是图片上传后会生成的名字不会出现重复。
    刚开始上传的时候,图片还是原名,因为要进行上传服务器的时候,要用到这个模型的参数,所以保存到本地的时候会保存动态生成的文件名,这个evaluation_directory_path_face返回的值就存到了数据库里,但是返回的这个值并不是字符串,而是一个文件型的变量

    代码:

    # 使用uuid创建唯一的图片名,并保存的路径和文件名一并返回
    def evaluation_directory_path_face(product_id, filename):
    	ext = filename.split('.')[-1]
    	filename = '{}.{}'.format(uuid.uuid4().hex[:10], ext)
    	return os.path.join("static/face", filename)
    
    # 需要上传图片的表
    class Group(models.Model):
    	
    	# 图片的字段或者文件的字段, 通过 upload_to 指定自己写好的fromat函数,
    	# 返回的是图片上传后会生成的名字不会出现重复
    	GImage = models.ImageField(null=True, blank=True,
    	     upload_to=evaluation_directory_path_face, 
    	     verbose_name="人脸识别图像", default='')
    
    
    

四:主从表的一些操作例子

url:  https://www.cnblogs.com/xiaogongjin/p/13288397.html  这边有一些别的博主写的博客,可以参考一下

我讲两句!!! 嗯…啊…哈哈哈没啥可说的。就这点b东西!

昨天是曼巴逝世一周年,曼巴精神一直感染着我,像他一样,永不放弃,对于困难,越艰难越要爱上挑战,不断提高自己。 Kobe Bean Bryant 是我永远的榜样。在自己选择的道路上即使自己没有天赋,也要尽自己的努力做好自己所能做到的!加油,曼巴精神永远记在我心!

在这里插入图片描述

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值