Reputation: 489
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.
Upvotes: 2
Views: 4669
Reputation: 489
It works out of the box with update 2.3.13. Check the changelog.
Thanks to Anton-Shutik for its Pull Request !
Upvotes: 0
Reputation: 15549
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
Upvotes: 1
Reputation: 489
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.
Upvotes: 4
Reputation: 888
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.
Upvotes: -1