首页 > 解决方案 > Django Rest Framework - OneToOne 反向关系

问题描述

我有一个自定义用户模型和用户配置文件模型。

class User(AbstractUser):
    """Custom User authentication class to use email as username"""
    username = None
    email = models.EmailField(verbose_name='email', max_length=255, unique=True,
                              error_messages={
                                  'unique': _(
                                          "A user is already registered with this email address"),
                              }, )

    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = []

    objects = UserManager()

    def __str__(self):
        return self.email


class UserProfile(models.Model):
    user = models.OneToOneField(User, to_field='email', on_delete=models.CASCADE)
    emp_id = models.CharField(max_length=20, blank=False, default='0', null=False)
    department = models.CharField(max_length=50, blank=True, default='', null=True)

我正在尝试编写一个结合这两种模型的序列化程序,以生成嵌套的 JSON。

例如:

{
  "email":"user@gmail.com",
  "is_active":true,
  "profile":
    {
      "emp_id":2,
      "department":2
    }
}

这就是我试图做的


class UserProfileSerializer(serializers.ModelSerializer):

    class Meta:
        model = UserProfile
        fields = ('id', 'user', 'emp_id', 'department')


class UserPairSerializer(serializers.ModelSerializer):
    profile = UserProfileSerializer(read_only=True)

    class Meta:
        model = User
        fields = ('id', 'email', 'is_active', 'profile')

但由于某种原因,profile我的回复中既没有该字段,也没有收到任何错误。我尝试遵循此文档:https ://www.django-rest-framework.org/api-guide/relations/

有什么问题,我该如何解决?

标签: djangodjango-rest-framework

解决方案


根据隐含引用this的文档,“反向”查询是使用小写的模型名称(在本例中为 user.userprofile)完成的。

所以你有两个选择:

您可以在模型related_name上的user字段上指定自定义。UserProfile

class UserProfile(models.Model):
    user = models.OneToOneField(User, to_field='email', on_delete=models.CASCADE, related_name='profile')

source或者,您在嵌套序列化程序上指定一个参数(请参阅文档):

class UserProfileSerializer(serializers.ModelSerializer):

    class Meta:
        model = UserProfile
        fields = ('id', 'user', 'emp_id', 'department')


class UserPairSerializer(serializers.ModelSerializer):
    profile = UserProfileSerializer(read_only=True, source='userprofile')

    class Meta:
        model = User
        fields = ('id', 'email', 'is_active', 'profile')

推荐阅读