In the serializer, country
is the object of Country Model, and I have added a PrimaryKeyRelatedField
with ending *_id
to get the id and use it to send from the front-end if there is any change.
The Address Serializer:
class AddressSerializer(serializers.ModelSerializer):
id = serializers.IntegerField()
country = CountrySerializer(read_only = True)
country_id = serializers.PrimaryKeyRelatedField(queryset = Country.objects.all(), source="country") #field added to get the id
class Meta:
model = Address
fields = '__all__'
class CompanySerializer(serializers.ModelSerializer):
category = CategorySerializer(read_only=True)
category_id = serializers.PrimaryKeyRelatedField(queryset = Category.objects.all(), source='category', allow_null=True)
addresses = AddressSerializer(many=True, read_only=False)
class Meta:
model = Company
fields = '__all__'
def update(self, instance, validated_data):
addresses = validated_data.pop('addresses')
instance = super().update(instance, validated_data)
address_list = []
for address in addresses:
address_id = address['id']
if address_id != 0:
address_instance = Address.objects.get(id = address_id)
address_instance.country_id = address['country_id']
address_instance.save()
elif address_id == 0:
address.pop('id', None)
address_list.append(Address.objects.create(**address))
instance.addresses.add(*address_list)
return instance
JSON Request TO UPDATE Company and addresses
{
"id":25,
"category_id":1,
"name":"COMPANY SA DE CV",
"addresses":[{
"id":1,
"country_id":2,
"content_type":36,
"object_id":25
}]
}
My problem is that, if I send (PATCH or PUT) in the request country_id
or the others PrimaryKeyRelatedField
, I receive the ERROR, since they don't appear in validated_data
.
I have tried with read_only=False
, write_only=True
in this field.
...
File "/Users/obedramales/Sites/webegin-project/webegin/app/serializers.py", line 214, in update
address_instance.country_id = address['country_id']
KeyError: 'country_id'
This is when it was updated from the company, but if I update just the address directly it does fine.
I would like to know what is the correct way to handle this please?
The models are defined like these:
class Company(SafeDeleteModel):
category = models.ForeignKey(Category, on_delete=models.CASCADE, null=True, blank=True)
code = models.CharField(max_length=10, null=True)
name = models.CharField(max_length=100)
addresses = GenericRelation('Address')
In this model I have a generic relationship from Address to Company. A company can have many addresses.
class Address(SafeDeleteModel):
content_type = models.ForeignKey(ContentType, related_name='model_addresses', on_delete=models.CASCADE)
object_id = models.PositiveIntegerField(null=True)
content_object = GenericForeignKey('content_type', 'object_id')
country = models.ForeignKey(Country, on_delete=models.CASCADE, null=True, blank=True)
CodePudding user response:
I think you need to set the country_id
field in the AddressSerializer
.
class AddressSerializer(serializers.ModelSerializer):
id = serializers.IntegerField()
country = CountrySerializer(read_only = True)
country_id = serializers.PrimaryKeyRelatedField(queryset = Country.objects.all(), source="country") #field added to get the id
class Meta:
model = Address
fields = '__all__'
extra_fields = ['country_id']
The country_id
field is not defined in the Address
class. So you need to set that field additionally.
CodePudding user response:
I tried changing the following line of code
address_instance.country_id = address['country_id']
to
address_instance.country = address['country']
and it works, When I send country_id
updates the correct id, but it is necessary to have country_id
declared
country = CountrySerializer(read_only = True)
country_id = serializers.PrimaryKeyRelatedField(source="country", queryset = Country.objects.all())
in JSON Request
...
"country_id": 3,
...