I'm usign Django Rest Framework where I have the following two serializers:
class ServiceSerializer(serializers.ModelSerializer): id = serializers.ReadOnlyField() class Meta: model = ServiceType fields = ('id', 'serviceName', 'servicePrice') class CompanyShortListSerializer(serializers.ModelSerializer): services = ServiceSerializer(many=True) class Meta: model = Company fields = ( 'id','name','address','cost_per_patient','cost_per_month','renting_fee','services')
The ServiceType model looks like this:
class ServiceType(models.Model): serviceName = EncryptedCharField(max_length=100, blank=True, verbose_name = "Typ usługi") servicePrice = EncryptedFloatField(null=True, blank=True, verbose_name = "Cena usługi", validators = [MinValueValidator(0.1), MaxValueValidator(999)]) company = models.ForeignKey(Company, related_name = 'services')
I would like to update the existing instances by changing the related services (e.g. deleting some of them). To achieve this I'm doing this:
def update(self, instance, validated_data): # Updates an exisitng Company with several services instance.name = validated_data['name'] instance.address = validated_data['address'] instance.cost_per_patient = validated_data['cost_per_patient'] instance.renting_fee = validated_data['renting_fee'] services_data = validated_data['services'] for item in services_data: updatedService = ServiceType( serviceName = item['serviceName'], servicePrice = item['servicePrice'], id=item['id'], company=instance) updatedService.save() return instance
The problem that I'm facing is that the service['id']
field is not provided - which means I get a KeyError 'id'
- although I added it explicitly in the ServiceSerializer
id
field.
EDIT
Here's an exemplary request (taken from Chrome) that I'm posting:
{ "id":49,"name":"Test 1", "address":"Testowa 1", "renting_fee":200, "cost_per_month":300, "cost_per_patient":null, "services":[ {"id":67,"serviceName":"Terapia","servicePrice":100}, {"id":68,"serviceName":"Terapia par","servicePrice":150}, {"id":69,"serviceName":"Terapia po angielsku","servicePrice":120} ] }
What am I doing wrong and how to get the ID of a an object(basically ServiceSerializer) using nested serializers?
EDIT no.2
When I print from the serializer update function I get the following:
print(self.data['services'])
gives me:
[ OrderedDict([('id', 67), ('serviceName', u'Terapia'), ('servicePrice', 100.0)]), OrderedDict([('id', 68), ('serviceName', u'Terapia par'), ('servicePrice', 150.0)]), OrderedDict([('id', 69), ('serviceName', u'Terapia po angielsku'), ('servicePrice', 120.0)]), OrderedDict([('id', 70), ('serviceName', u'Terapia grupowa'), ('servicePrice', 140.0)]) ]
However, print(services_data)
gives the following (basically the same, but without the id):
[ OrderedDict([(u'serviceName', u'Terapia'), (u'servicePrice', 100.0)]), OrderedDict([(u'serviceName', u'Terapia par'), (u'servicePrice', 150.0)]), OrderedDict([(u'serviceName', u'Terapia po angielsku'), (u'servicePrice', 120.0)]) ]
And the ids
get lost ...
EDIT no.3
According to the Django Rest Framework docs If certain field will be shall be in the serializer output representation it should be a HiddenField
. This however requires a default
value ... I have checked that and indeed using this HiddenField with a default value 'solves' the problem - the ID is there in validated_data. The problem is that the id
is not correct. Is there a possibility to set this id
to the value of the object sent to the serializer?
Ok - I think I found the answer after ... carefully reading the docs :)
So according to the docs the id
field could be set to a ModelField like this:
id = serializers.ModelField(model_field=ServiceType()._meta.get_field('id'))
Indeed, after adding this line the id
field is present in validated_data :)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With