序列化器中一对一关系的输出查找字段
Output lookup fields in serialiser for OneToOne relationship
我想在我的 API 字段中输出来自两个不同(相关)模型的数据。
我有这个 models.py:
class User(AbstractBaseUser):
first_name = models.CharField(max_length=30, blank=True, null=True)
surname = models.CharField(max_length=30, blank=True, null=True)
def __str__(self):
return "%s %s" % (self.first_name, self.surname) # I don't want to change this.
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, related_name='profile', null=True, blank=True)
first_nameUnregistered = models.CharField(max_length=120, null=True, blank=True)
surnameUnregistered = models.CharField(max_length=120, null=True, blank=True)
这是我的序列化程序:
class ProfileSerialiser(serializers.HyperlinkedModelSerializer):
user = serializers.StringRelatedField(many=False)
class Meta:
model = Profile
fields = ('first_nameUnregistered', 'surnameUnregistered', 'user')
我的观点:
class ProfileViewSet(viewsets.ModelViewSet):
queryset = Profile.objects.all()
serializer_class = ProfileSerialiser
现在我去 /api/profliles 端点时看到的是:
[
{
"first_nameUnregistered": "",
"surnameUnregistered": "",
"user": "The full user name, coming from def __str__(self):"
},
[...]
我想得到类似的东西:
[
{
"first_nameUnregistered": "",
"surnameUnregistered": "",
"user.first_name": "first name"
"user.surnamee": "surname"
},
[...]
profile__user.first_name
之类的查找似乎不起作用,我无法合并这两个查询集,因为它们来自不同的模型,而且我无法在序列化程序的 fields
定义中使用属性。我怎样才能达到我想要的?
解决方案
感谢@Jan Giacomelli 为我指出 source
关键字。我必须添加一个默认值,因为如果字段为空,Django Rest Framework 将抛出错误:
Got AttributeError when attempting to get a value for field `user__first_name` on serializer `ProfileSerialiser`.
The serializer field might be named incorrectly and not match any attribute or key on the `Profile` instance.
Original exception text was: 'NoneType' object has no attribute 'first_name'.
因此,我的完整工作代码是:
class ProfileSerialiser(serializers.HyperlinkedModelSerializer):
user__first_name = serializers.CharField(source='user.first_name', default='name')
user__surname = serializers.CharField(source='user.surname', default='name')
class Meta:
model = Profile
fields = ('id', 'first_nameUnregistered', 'surnameUnregistered', 'user__first_name', 'user__surname')
您可以在字段选项中使用 source 关键字参数。这样您就可以访问相关对象的属性。
将序列化程序更改为:
class ProfileSerialiser(serializers.HyperlinkedModelSerializer):
user__first_name = serializers.CharField(source='user.first_name')
user__surname = serializers.CharField(source='user.last_name')
class Meta:
model = Profile
fields = ('first_nameUnregistered', 'surnameUnregistered', 'user__first_name', 'user__surname')
它将return输出如下:
[
{
"first_nameUnregistered": "",
"surnameUnregistered": "",
"user__first_name": "first name"
"user__surname": "surname"
},
[...]
我想在我的 API 字段中输出来自两个不同(相关)模型的数据。
我有这个 models.py:
class User(AbstractBaseUser):
first_name = models.CharField(max_length=30, blank=True, null=True)
surname = models.CharField(max_length=30, blank=True, null=True)
def __str__(self):
return "%s %s" % (self.first_name, self.surname) # I don't want to change this.
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, related_name='profile', null=True, blank=True)
first_nameUnregistered = models.CharField(max_length=120, null=True, blank=True)
surnameUnregistered = models.CharField(max_length=120, null=True, blank=True)
这是我的序列化程序:
class ProfileSerialiser(serializers.HyperlinkedModelSerializer):
user = serializers.StringRelatedField(many=False)
class Meta:
model = Profile
fields = ('first_nameUnregistered', 'surnameUnregistered', 'user')
我的观点:
class ProfileViewSet(viewsets.ModelViewSet):
queryset = Profile.objects.all()
serializer_class = ProfileSerialiser
现在我去 /api/profliles 端点时看到的是:
[
{
"first_nameUnregistered": "",
"surnameUnregistered": "",
"user": "The full user name, coming from def __str__(self):"
},
[...]
我想得到类似的东西:
[
{
"first_nameUnregistered": "",
"surnameUnregistered": "",
"user.first_name": "first name"
"user.surnamee": "surname"
},
[...]
profile__user.first_name
之类的查找似乎不起作用,我无法合并这两个查询集,因为它们来自不同的模型,而且我无法在序列化程序的 fields
定义中使用属性。我怎样才能达到我想要的?
解决方案
感谢@Jan Giacomelli 为我指出 source
关键字。我必须添加一个默认值,因为如果字段为空,Django Rest Framework 将抛出错误:
Got AttributeError when attempting to get a value for field `user__first_name` on serializer `ProfileSerialiser`.
The serializer field might be named incorrectly and not match any attribute or key on the `Profile` instance.
Original exception text was: 'NoneType' object has no attribute 'first_name'.
因此,我的完整工作代码是:
class ProfileSerialiser(serializers.HyperlinkedModelSerializer):
user__first_name = serializers.CharField(source='user.first_name', default='name')
user__surname = serializers.CharField(source='user.surname', default='name')
class Meta:
model = Profile
fields = ('id', 'first_nameUnregistered', 'surnameUnregistered', 'user__first_name', 'user__surname')
您可以在字段选项中使用 source 关键字参数。这样您就可以访问相关对象的属性。
将序列化程序更改为:
class ProfileSerialiser(serializers.HyperlinkedModelSerializer):
user__first_name = serializers.CharField(source='user.first_name')
user__surname = serializers.CharField(source='user.last_name')
class Meta:
model = Profile
fields = ('first_nameUnregistered', 'surnameUnregistered', 'user__first_name', 'user__surname')
它将return输出如下:
[
{
"first_nameUnregistered": "",
"surnameUnregistered": "",
"user__first_name": "first name"
"user__surname": "surname"
},
[...]