Reputation: 5
I'm trying to create an update function for one of my serializers which represents a Company
where some people (user of my app) are admin
. However when I make my request with Postman to update my Company object, it seems that my serializer does not get all the data i PUT
in my API.
I have tried to use the full user object serializer in my Company serializer but in this case i must specify data I don't need and it does not even work.
When i PUT
the name of my company like so:
{
"id": 1,
"admins": [
5,
6,
7,
9,
11
],
"name": "Mon entreprise"
}
My api responds this (the users with IDs 6 and 11 were added using the admin panel):
{
"name": "Mon entreprise",
"logo": "http://localhost:8000/api/companies/1/mwe.jpg",
"admins": [
6,
11
]
}
I tried this to see what data were passed through the API
def update(self, instance, validated_data):
print (validated_data)
and the output was:
{'name': "Mon entreprise"}
My serializer:
class CompanySerializer(serializers.ModelSerializer):
admins = serializers.PrimaryKeyRelatedField(many=True, read_only=True)
class Meta:
model = Company
fields = ('name', 'logo', 'admins',)
def update(self, instance, validated_data):
print (validated_data)
instance.logo = validated_data.get('logo', instance.logo)
instance.name = validated_data.get('name', instance.name)
instance.save()
admin_list = validated_data.get('admins')
print (admin_list)
return instance
my model:
class Company(models.Model):
admins = models.ManyToManyField(User, related_name='admins')
logo = models.ImageField(blank=True)
name = models.CharField(max_length=200)
I don't understand why I only have {'name': "Mon entreprise"}
as I added an admins
field in my json for the PUT
request
Upvotes: 0
Views: 1422
Reputation: 2664
I've had the very same problem. It seems that PrimaryKeyRelatedField
does not work properly with many=True
for writing. In my team we have come up with the following temporary solution until we have time to dig more into why this does not work as expected:
class PrimaryKeyRelatedListField(serializers.ListField):
def __init__(self, queryset=None, **kwargs):
assert queryset is not None, 'queryset must be specified for PrimaryKeyRelatedListField'
self.child = serializers.PrimaryKeyRelatedField(queryset=queryset)
super().__init__(**kwargs)
def get_value(self, dictionary):
dictionary = dictionary.copy()
keys = []
for k, _ in dictionary.items():
if k.startswith(f'{self.field_name}['):
keys.append(k)
for k in keys:
dictionary.appendlist(self.field_name, dictionary.getlist(k)[0])
return super().get_value(dictionary)
def to_representation(self, data):
return super().to_representation(data.all())
Hope this helps you.
Ok, so I've re read your question, and you have set read_only=True
to your admins
field, this will make DRF ignore whatever data you are sending... therefore these data will not reach the update()
method of your serializer.
Upvotes: 2