【问题标题】:Django REST:Combine two modelsDjango REST:结合两个模型
【发布时间】:2016-03-07 11:59:30
【问题描述】:

我刚开始使用 django rest 框架,这可能是一个老问题,但到目前为止,我还没有在 SO 上找到任何正确的答案。

我想向 DRF 提供的现有用户模型添加一些额外的配置文件字段。阅读文档后,我选择创建一个新的 CustomUser 模型并通过外键将其与默认的 User 模型相关联。

当我尝试序列化 CustomUser 模型时,问题出现了。我希望json是这样的:

{
  "username" : "from_default_user_model",
  "extra_field" : "from_custom_user_model"
}  

但是通过使用如下嵌套的序列化器,我得到了嵌套的 json 表示。

class UserSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = ('username',)

class CustomUserSerializer(serializers.ModelSerializer):
    user  = UserSerializer()
    class Meta:
        model = CustomUser
        fields = ('extra_field',)

嵌套的看起来像这样:

{
    "username" : "from_default_user_model",
    "user" : 
           {
               "extra_field" : "from_custom_user_model"
           }
}

我想要的是某种类似于两个表之间的数据库连接,它只生成一个普通表,而不是嵌套表。我怎样才能做到这一点?

【问题讨论】:

    标签: json django django-rest-framework


    【解决方案1】:

    我猜您将使用 Django 的默认用户模型作为 OneToOneField 与您的自定义用户模型。您不需要另一个用于 User 模型的序列化程序。由于额外的字段将在 CustomUser 中,因此只需为 Custom User 编写一个序列化程序就足够了。

    from django.contrib.auth.models import User
    class CustomUser(models.Model):
        user = models.OneToOneField(User)
        # Add your extra fields here.
    

    这就是你的做法:

    CustomUserSerializer(serializers.ModelSerializer):
        username = Serializers.CharField(source='user.username')
        email = Serializers.EmailField(source='user.email')
    
        class Meta:
            model = CustomUser
            fields = ('username', 'email', 'extra_fields_from_CustomUser',)
    

    谢天谢地,source 可让您轻松访问 OneToOneField,这样您就不需要其他任何东西了。

    【讨论】:

    • 这解决了我的问题,但是再次指定每个字段的类型可能有点乏味,尤其是当您不确定原始字段类型时。例如,您必须指定last_login = serializer.DateTimeField(source='user.last_login') 而不是DateField(source='user.last_login')。后者会给你一个断言失败。
    • 是的,这可能很乏味,但你只会为用户模型做这件事,因此不需要太多额外的工作。
    【解决方案2】:

    在 CustomUser 模型上,创建快捷方式属性,然后将其添加到 meta 中的字段定义中

    @property
    def username(self):
        return self.user.username
    
    class meta:
        model = ...
        fields = ("username", "extra-field",...)
    

    【讨论】:

    • 您能详细说明一下吗?我在尝试您的答案时遇到 ImproperlyConfigured 错误,谢谢。
    猜你喜欢
    • 2014-01-09
    • 2020-05-24
    • 1970-01-01
    • 1970-01-01
    • 2014-08-20
    • 2013-11-11
    • 2021-10-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多