问题描述
我希望嵌套模型的序列化不包括每个实例的字段名称,因为序列化中只有一个字段。
我在 models.py
中有以下模型:
class Language(models.Model):
name = models.CharField(max_length=32)
code = models.CharField(max_length=32,unique=True)
class Person(models.Model):
name = models.CharField(max_lenght=128)
languages = models.ManyToManyField(Language,blank=True) # the languages this person speaks
languages 是 ManyToManyField
,因为一个人可以说多种语言,而一种语言可以被多人使用。
我在 serializers.py
中有以下序列化程序:
class LanguageSerializer(serializers.ModelSerializer):
class Meta:
model = Language
fields = ['code']
class PersonSerializer(serializers.ModelSerializer):
languages = LanguageSerializer(many=True,required=False)
class Meta:
model = Person
fields = ['name','languages']
目前序列化为 JSON 看起来像这样:
{"name": "Elizabeth II","languages": [{"code":"en"},{"code":"fr"}]}
但我希望它看起来像这样:
{"name": "Elizabeth II","languages": ["en","fr"]}
而且这应该不会有问题,因为在语言序列化中只有一个字段,永远不会有另一个字段,所以"code"
字段名称是多余的。
如何实现?
更新:当通过 DRF 从 JSON 创建一个新人时,如何使它也能工作?
我在 views.py
中有以下视图:
class CreatePersonView(generics.CreateAPIView):
queryset = Person.objects.all()
serializer_class = PersonSerializer
解决方法
您可以像这样更改序列化程序。
class PersonSerializer(serializers.ModelSerializer):
languages = serializers.SerializerMethodField()
class Meta:
model = Person
fields = ['name','languages']
def get_languages(self,obj):
return obj.languages.all().values_list('name')
,
这就是我实现想要的行为的方式:
serializers.py
:
class LanguageRelatedField(serializers.StringRelatedField):
def get_queryset(self):
return Language.objects.all()
def to_representation(self,instance):
return instance.code
def to_internal_value(self,data):
try:
return Language.objects.get(code=data)
except Language.DoesNotExist:
raise serializers.ValidationError('Language {} could not be recognized'.format(data))
class PersonSerializer(serializers.ModelSerializer):
languages = LanguageRelatedField(many=True,required=False)
class Meta:
model = Person
fields = ['name','languages']