Good day,
I'm trying to do a PUT request that contains a nested-object and I can't get the province to update correctly. There didn't seem to be anything obvious in the django-rest-framework docs to help with this and I've investigated the solutions of a few other similar problems but none have helped (set many=false
, change to ModelSerializer
, specialized serializers, etc.).
Everything else about the address will update correctly and return a 200 response (no errors in django logs either). Am I wrong to assume that django-rest-framework handles this all for me for free? Do I have to override the update and create methods within the serializer to validate and save the nested-object?
I'm thinking it's because I have the province serializer set to read_only
within the address serializer. However, if I remove the read_only
modifier on the province serializer, it gives an error about the province already existing:
{
"province": {
"province": [
"valid province with this province already exists."
]
}
}
Which is behaviour I do not expect and don't know how to resolve. I am not trying to add or update the province. I just want to change the province code in the address.province field and I can't use a string "MB" because it expects an object. I effectively want this behaviour:
UPDATE agent_business_address
SET province = 'MB'
WHERE agent_id = 12345;
-- agent_business_address.province has a foreign key constraint on valid_province.province
-- valid_province is populated with all the 2-letter abbreviations for provinces(
I make this PUT request to /api/agent-business-address/
{
"address": "123 Fake St",
"agent_id": 12345,
"city": "Calgary",
"dlc": "2021-10-11 14:03:03",
"operator_id": 4,
"postal_code": "A1B 2C3",
"province": {
"description": "Manitoba",
"province": "MB"
},
"valid_address": "N"
}
That is received by this ViewSet:
class AgentBusinessAddressViewSet(viewsets.ModelViewSet):
queryset = AgentBusinessAddress.objects.all()
serializer_class = AgentBusinessAddressSerializer
Relevant serializers:
class AgentBusinessAddressSerializer(serializers.HyperlinkedModelSerializer):
province = ValidProvinceSerializer(read_only=True) # Removing the read_only causes the error above.
class Meta:
model = AgentBusinessAddress
fields = ('agent_id', 'operator_id', 'dlc', 'address', 'city', 'province', 'postal_code', 'valid_address')
class ValidProvinceSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = ValidProvince
read_only_fields = ('operator_id', 'dlc')
fields = ('province', 'description')
Relevant models:
class AgentBusinessAddress(models.Model):
agent = models.OneToOneField(Agent, models.DO_NOTHING, primary_key=True)
operator_id = models.SmallIntegerField()
dlc = models.DateTimeField()
address = models.CharField(max_length=100)
city = models.CharField(max_length=80)
province = models.ForeignKey('ValidProvince', models.DO_NOTHING, db_column='province')
postal_code = models.CharField(max_length=7)
valid_address = models.CharField(max_length=1)
class Meta:
managed = False
db_table = 'agent_business_address'
class ValidProvince(models.Model):
province = models.CharField(primary_key=True, max_length=2)
operator_id = models.SmallIntegerField()
dlc = models.DateTimeField()
description = models.CharField(max_length=30, blank=True, null=True)
class Meta:
managed = False
db_table = 'valid_province'
Any help would be appreciated.