I have the following Serializer using the Django REST Framework.
This is what I have so far...
serializer.py
class ProductSerializer(serializers.ModelSerializer):
score = serializers.SerializerMethodField('get_this_score')
class Meta:
model = Product
fields = ('id', 'title', 'active', 'score')
def get_this_score(self, obj):
profile = Profile.objects.get(pk=19)
score = [val for val in obj.attribute_answers.all() if val in profile.attribute_answers.all()]
return (len(score))
urls.py
url(r'^products/(?P<profile_id>.+)/$', ProductListScore.as_view(), name='product-list-score'),
There are a few issues with this snippet of code.
1) The pram pk=19 is hardcoded it should be self.kwargs['profile_id'].
I have tried and tried, but I don't know how to pass kwarg into the method and cannot get profile_id to work. i.e. I cannot get it from the url.
2) Should any of this code be in models? I have tried adding to models, but again can pass the args.
models.py i.e. method class
def get_score(self, profile):
score = [val for val in self.attribute_answers.all() if val in
profile.attribute_answers.all()]
return len(score)
Serializers are passed a context dictionary, which contains the view instance, so you could get the profile_id by doing something like this:
view = self.context['view']
profile_id = int(view.kwargs['profile_id'])
However in this case I don't think you need to do that as 'obj' will in any case be set to the profile instance.
And yes, you could put the 'get_this_score' method on the model class instead. You'd still need the 'SerializerMethodField', but it would simply call 'return obj.get_this_score(...)', setting any arguments from the serializer context.
Note that the serializer context will also include 'request', so you can also access 'request.user' if needed.
To answer jason's question response to Tom's answer you can access the request object via the same context mechanism like so. You reference the request objects from the ModelMethod definition, you don't pass them. I was able to use this to access the current request.user object as below:
class ProductSerializer(serializers.ModelSerializer):
score = serializers.SerializerMethodField('get_this_score')
class Meta:
model = Product
fields = ('id', 'title', 'active', 'score')
def get_this_score(self, obj):
profile = self.context['request'].user
score = [val for val in obj.attribute_answers.all() if val in profile.attribute_answers.all()]
return (len(score))
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