I am working on an discussion app in Django, that has Threads, Posts, Replies and Votes. Votes uses Generic Foreign Keys and Content Types to ensure a user can only vote once on a specific Thread/Post/Reply.
Vote model looks like this:
VOTE_TYPE = (
(-1, 'DISLIKE'),
(1, 'LIKE'),
)
class Vote(models.Model):
user = models.ForeignKey(User)
content_type = models.ForeignKey(ContentType,
limit_choices_to={"model__in": ("Thread", "Reply", "Post")},
related_name="votes")
object_id = models.PositiveIntegerField()
content_object = generic.GenericForeignKey('content_type', 'object_id')
vote = models.IntegerField(choices=VOTE_TYPE)
objects = GetOrNoneManager()
class Meta():
unique_together = [('object_id', 'content_type', 'user')]
Vote Serializer:
class VoteSerializer(serializers.ModelSerializer):
class Meta:
model = Vote
The view to handle a vote:
@api_view(['POST'])
def discussions_vote(request):
if not request.user.is_authenticated():
return Response(status=status.HTTP_404_NOT_FOUND)
data = request.DATA
if data['obj_type'] == 'thread':
content_type = ContentType.objects.get_for_model(Thread)
print content_type.id
info = {
'content_type': content_type.id,
'user': request.user.id,
'object_id': data['obj']['id']
}
vote = Vote.objects.get_or_none(**info)
info['vote'] = data['vote']
ser = VoteSerializer(vote, data=info)
if ser.is_valid():
print "Valid"
else:
pprint.pprint(ser.errors)
return Response()
request.DATA content:
{u'vote': -1,
u'obj_type': u'thread',
u'obj':
{
...
u'id': 7,
...
}
}
When I vote, Django Rest Framework serializer throws an error:
Model content type with pk 149 does not exist.
149 is the correct id for the ContentType for the Thread model, according to
print content_type.id
I'm pretty much at a loss at what could be causing this...
In Django, a GenericForeignKey is a feature that allows a model to be related to any other model in the system, as opposed to a ForeignKey which is related to a specific one.
You probably have already seen Django's ContentTypes and wondered how to use it or what is it for anyway. Basically it's a built in app that keeps track of models from the installed apps of your Django application. And one of the use cases of the ContentTypes is to create generic relationships between models.
The issue is probably that you have a generic foreign key in there, which could be linked to any type of model instance, so there's no default way of REST framework determining how to represent the serialized data.
Take a look at the docs on GFKs in serializers here, hopefully it should help get you started... http://www.django-rest-framework.org/api-guide/relations#generic-relationships
If you're still finding it problematic then simply drop out of using serializers altogether, and just perform the validation explicitly in the view, and return a dictionary of whatever values you want to use for the representation.
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