4
votes

The model:

class Item(models.Model):
    company = models.ForeignKey(Company, on_delete=models.CASCADE)
    item_num = models.IntegerField()
    # other fields...
    class Meta:
       unique_together = [('company', 'item_num') ]

Serializer:

class ItemSerializer(serializers.ModelSerializer):
    class Meta:
        model = Item
        fields = ('company_id', 'item_num', ) 

The problem is that django rest framework generates a ReadOnlyField() for the company_id field, so this field is not editable when I create a new instance in view code like this:

s = ItemSerializer(data=request.POST)
s.save()

I also lose the default UniqueTogetherValidator that is defined in the model. Though, if I change the serializer field name from 'company_id' to 'company', I do get the validator, as drf will generate PrimaryKeyRelatedField so it will be editable.

How can I still name my foreign key objects like 'company_id', because I do prefer naming them like this, and still get the default validation and saving behavior? Preferably without adding to much code to the serializer.

1

1 Answers

4
votes

company_id is a read-only field because it lacks a proper definition in the Model for the serializer to understand it. Steps to get it working:

  1. Add an explicit field definition
  2. Add the constraint

Serializer would be:

class ItemSerializer(serializers.ModelSerializer):
    company_id = serializers.PrimaryKeyRelatedField(source=company, queryset=Company.objects.all())
    class Meta:
        model = Item
        fields = ('company_id', 'item_num', )
        validators = [
            UniqueTogetherValidator(
                queryset=Item.objects.all(),
                fields=('company_id', 'item_num')
            )
        ]