ss7
ss7

Reputation: 3012

Django Rest Framework Generic Relationships and ViewSets

I have a model Comment that can go on either Project or Task.

class Comment(BaseCommentModel):
    author = models.ForeignKey(settings.AUTH_USER_MODEL)
    content_type = models.ForeignKey(
            ContentType,
            verbose_name=_('content type'),
            related_name="contenttype_set_for_%(class)s"
    )
    object_pk = models.TextField(_('object ID'))
    content_object = GenericForeignKey(ct_field="content_type", fk_field="object_pk")

Project and Task have the field set up as:

comments = GenericRelation(Comment)

Comments can be created on either Projects or Tasks so there should be a viewset for each:

class ProjectCommentViewSet(viewsets.ViewSet):

class TaskCommentViewSet(viewsets.ViewSet):

And those would display the comments related to each model.

But what I don't understand is:

  1. How do I set up the create/update/delete in a viewset for the Comment model so that the comment is created with the correct relationship?

  2. How do I filter inside the viewsets to display comments related to that model? I can't use select_related because the Comment doesn't have a Project or Task field.

  3. How do I write the HyperlinkedModelSerializers for these relationships? Do I need to add a HyperlinkedIdentityField to CommentSerializer() and then HyperlinkedRelatedFields to the User, Project, and Task Serializers? Or how do I set this up?

Thanks for any help provided, I could really use some direction here.

I'm having trouble understanding how the relationships on the models translate to the serializers and viewsets. And also how to handle the relationships when using generic relations.

Upvotes: 1

Views: 1187

Answers (1)

Aaron Lelevier
Aaron Lelevier

Reputation: 20820

The key is to use PrimaryKeyRelatedField. This will return an list of id's, which is what you would use for a create/update for a Project model instance with related Comment records.

Other than that, GenericRelation behaves just like other ORM relationships within django-rest-framework.

In the ViewSet Serializer define it like so:

from rest_framework import viewsets, serializers

class ProjectCommentViewSet(viewsets.ViewSet):
    queryset = Project.objects.all()
    serializer_class = ProjectSerializer

class ProjectSerializer(serializers.ModelSerializer):
    comments = serializers.PrimaryKeyRelatedField(
        queryset=Comment.objects.all(), many=True, required=False)

    class Meta:
        model = Project
        fields = ('id', 'etc...', 'comments',)

Upvotes: 1

Related Questions