简体   繁体   English

如何使用Django REST框架与外键的默认值模型?

[英]How to use Django REST framework with a model with default value for foreign key?

Django==1.5.5 Django的== 1.5.5
djangorestframework==2.3.8 djangorestframework == 2.3.8

I have a model with a Foreignkey: 我有一个带外键的模型:

class Role(models.Model):
    name = models.CharField("Name", unique=True)

    def __unicode__(self):
        return unicode(_(self.name))

class Worker(models.Model):
    name = models.CharField("Name")
    role = models.ForeignKey(Role, default=1)

I add a REST api to this model: 我在这个模型中添加了一个REST api:

class WorkerSerializer(serializers.ModelSerializer):
    role = serializers.PrimaryKeyRelatedField(required=False, read_only=False)

    class Meta:
        model = Worker

class WorkerAPIList(generics.ListCreateAPIView):
    model = Worker
    serializer_class = WorkerSerializer

When I create an new worker with a POST request with no role given, it can't pick the default value in the model and return an error: 当我使用没有赋予角色的POST请求创建新工作程序时,它无法在模型中选择默认值并返回错误:

ValueError: Cannot assign None: "Worker.role" does not allow null values.

Any help would be appreciated. 任何帮助,将不胜感激。
Thanks 谢谢

NB: I use PrimaryKeyRelatedField because Role.name field is translated by django-dbgettext , so I can't use it in REST API. 注意:我使用PrimaryKeyRelatedField因为Role.name字段由django-dbgettext翻译,所以我不能在REST API中使用它。

Edit: a row with id=1 in Role table already exists. 编辑:角色表中id = 1的行已存在。

I found a solution: adding a field level validation to the serializer: 我找到了一个解决方案:向序列化器添加字段级验证:

class WorkerSerializer(serializers.ModelSerializer):
    ...

    def validate_role(self, attrs, source):
        "Set a default role if needed."
        value = attrs[source]
        if value is None:
            attrs[source] = Role.objects.get(id=Worker.role.field.default)
        return attrs

ref: django Rest framework doc ref: django Rest框架doc

It works, but seems quite heavy. 它有效,但看起来很重。

Absence of default value was a design decision. 没有默认值是一个设计决策。 Please check the following issue for more details, they also mention how to correctly set default value yourself by overriding field class, which seems much cleaner then overriding serializer. 请查看以下问题以获取更多详细信息,他们还提到了如何通过覆盖字段类来自己正确设置默认值,这似乎比覆盖序列化程序更清晰。

https://github.com/tomchristie/django-rest-framework/issues/988 https://github.com/tomchristie/django-rest-framework/issues/988

It works out of the box with update 2.3.13. 它开箱即用,更新2.3.13。 Check the changelog . 检查更改日志

Thanks to Anton-Shutik for its Pull Request ! 感谢Anton-Shutik的Pull Request!

Your foreign key can have a default as long as it exists. 只要存在,您的外键就可以有默认值。 It can have a null if you set null=True but a foreign key means that their should be a matching ID row in the Roles table. 如果设置null = True,则它可以为null,但外键表示它们应该是Roles表中的匹配ID行。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM