自定义Serializer序列化字段,动态改变field参数


问题案例
在使用Django时候,经常需要用到rest_framework中的Serializer来序列化返回的Model数据。

如果你遇到这么个场景,你有一个User模型,在某个场景用户有权限访问name、sex 、age这三个字段,另一个场景访问name、hobby字段,那是不是需要创建两个Serializer ,如果更多需求,那会显得很笨拙,这时候如果Serializer的field字段在外部可以传进去,那岂不是很符合需求

# 模型类

from django.db import models

class User(models.Model):
  name = models.CharField(max_length=20)
  sex = models.BooleanField()
  age = models.IntegerField()
  hobby = models.CharField(max_length=20)
  work = models.CharField(max_length=20)
  tel = models.CharField(max_length=20)

  

# Serializer序列化类

class Sence1Serializer(serializers.ModelSerializer):
  class Meta:
    model = User
    fields = ("name", "sex", "age")

class Sence2Serializer(serializers.ModelSerializer):
  class Meta:
    model = User
    fields = ("name", "hobby")

  



解决方法

# Serializers序列化
from rest_framework import serializers
class DynamicFieldsModelSerializer(serializers.ModelSerializer):
    def __init__(self, *args, **kwargs):
        fields = kwargs.pop('fields', None) # 提取fields
		
		# 实例化父类
        super(DynamicFieldsModelSerializer, self).__init__(*args, **kwargs)

        if fields is not None:
            # 删除fields参数中未指定的任何字段
            allowed = set(fields)
            existing = set(self.fields.keys())
            if allowed:
                for field_name in existing - allowed:
                    self.fields.pop(field_name)
            else:
            	# fields参数为空,则取全部字段
                pass

 

# 继承自定义的类

class Sence3Serializer(DynamicFieldsModelSerializer):
  class Meta:
    model = User
    fields = "__all__" # 这里可以写全部,在外面传fields修改

  

# 视图函数中可以写

from .serializers import Sence3Serializer
from .models import User

def Sence3View(request):
  user = User.object.filter(hobby="篮球").all()
  data = Sence3Serializer(user, many=True, fields=("name", "sex", "age")).data # 这里在fields里传入
  print(data)
  return JsonResponse({'code': "ok", "data": data})

  

 

posted @ 2022-02-23 17:42  7411  阅读(252)  评论(0)    收藏  举报