简体   繁体   中英

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

Django==1.5.5
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:

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:

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.

Edit: a row with id=1 in Role table already exists.

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

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

It works out of the box with update 2.3.13. Check the changelog .

Thanks to Anton-Shutik for its 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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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