ttt
ttt

Reputation: 300

Filtering objects returned by the relation (set.all) in Django

I am trying to solve the filtering of objects returned by set.all. I would like to display objects that are strictly assigned to the currently logged in user.

Below is a pseudo-code that illustrates the situation.

class Tags(models.Model):
    pass
    
class Comment(models.Model):
    creator = models.ForeignKey(... related_name='example')
    tag = models.ManyToManyField(Tags)

In the generic detail "tag" view

def get_context_data(self, **kwargs):
    context = super().get_context_data(**kwargs)
    context['author_objects'] = Comment.objects.filter(creator=self.request.user)
    return context

In a detail tag template, I am using set.all to return the callback objects. However, these are all assigned objects, and I would like to filter them.

{% for comment in tags.comment_set.all %}
     <a href="{% url 'comment-detail' comment.id %}">{{ comment.title }}</a>
{% endfor %}

I have tried many solutions to display user-created comments (even with 'author objects', nested loops) but I get all assigned objects or nothing. I suspect that the context is not working, but it was about visualizing the situation in the best possible way.

Upvotes: 2

Views: 67

Answers (1)

willeM_ Van Onsem
willeM_ Van Onsem

Reputation: 477160

You can specify the QuerySet with a Prefetch(…) expression [Django-doc] to retrieve a filtered set of comments.

You do this by overriding the get_queryset(…) [Django-doc] with:

from django.db.models import Prefetch

class MyView(SomeView):
    model = Tags
    
    def get_queryset(self):
        return super().get_queryset().prefetch_related(
            Prefetch(
                'comment_set',
                queryset=Comment.objects.filter(creator=self.request.user)
            )
        )

There is no need to alter the get_context_data. By specifying the Prefetch object, comment_set will only contain comments with self.request.user as creator.

Upvotes: 1

Related Questions