15π
Iβm not a big fan of this request parsing pattern. From what I understand, you want to be able to see all the contactβs details when you retrieve an AmountGiven
object and at the same time be able to create and update AmountGiven
by just providing the contact id.
So you can change your AmountGiven
serializer to have 2 fields for the contact
model field. Like this:
class AmountGivenSerializer(serializers.ModelSerializer):
contact_detail = ContactSerializer(source='contact', read_only=True)
class Meta:
model = AmountGiven
depth = 1
fields = (
'id', 'contact', 'contact_detail', 'amount', 'given_date', 'created'
)
Note that the contact_detail
field has a source
attribute.
Now the default functionality for create and update should work out of the box (validation and everything).
And when you retrieve an AmountGiven
object, you should get all the details for the contact in the contact_detail
field.
Update
I missed that you need to check whether the Contact
belongs to a user (however, I donβt see a user
field on your Contact
model, maybe you missed posting it). You can simplify that check:
class AmountGivenViewSet(viewsets.ModelViewSet):
serializer_class = AmountGivenSerializer
def perform_create(self, serializer):
contact = serializer.validated_data.get('contact')
if contact.user != self.request.user:
raise ValidationError({'contact': ['Not a valid contact']})
serializer.save()
1π
Override the __init__()
method of AmountGivenSerializer
as
class AmountGivenSerializer(serializers.ModelSerializer):
def __init__(self, *args, **kwargs):
super(AmountGivenSerializer, self).__init__(*args, **kwargs)
if 'view' in self.context and self.context['view'].action != 'create':
self.fields.update({"contact": ContactSerializer()})
class Meta:
model = AmountGiven
depth = 1
fields = (
'id', 'contact', 'amount', 'given_date', 'created'
)
Description
The issue was the DRF expects a dict like object from contact
field since you are defined a nested serializer
. So, I removed the nested relationship dynamically with the help of overriding the __init__()
method
0π
For those who got here but have relatively simple serializers, this error can also occur when the request data is malformed, in my case JSON encoded twice.
The serializer will decode the JSON, but as it is encoded twice request.data
will still be a string. The error therefore makes sense as a "dictionnary" was expected, but we still have a "string".
You can check the output of the following to confirm whether this is the issue you are experiencing:
print(type(request.data)) # Should be <class 'dict'>
- Apps aren't loaded yet exception occurs when using multi-processing in Django
- How to get dict of model objects keyed by field