Django - How to query a list inside of a filter method

Viewed 1005

I am new to Django and I want to query a list inside of an object. I have a list of Batches and each batch has a BatchComment list. Both of them has a User property. What I want to do is get batches where user has a comment and only get ones where the last comment is not made by the user. How can I achieve this?

Currently I am retrieving batches that user has comment by Batch.objects.filter(comments__user=self.request.user)

I want something like Batch.objects.filter(comments__user=self.request.user).filter(comments_last__user!=self.request.user)

Here are my models:

class Batch(TimeStampMixin):
    note = models.TextField(max_length=1000)
    image_url = models.URLField()

    class Meta:
        db_table = 'batches'
        ordering = ['-created_at']


class BatchLogComment(TimeStampMixin):
    body = models.TextField(max_length=500)
    batch = models.ForeignKey(Batch, on_delete=models.CASCADE, related_name='comments')
    user = models.ForeignKey(
        User, on_delete=models.SET_NULL, blank=True, null=True, related_name='comments')

    class Meta:
        db_table = 'batch_log_comments'
        ordering = ['-created_at']
2 Answers

We can use a subquery to obtain the last user, and then filter accordingly:

from django.db.models import OuterRef, Subquery, Q

Batch.objects.annotate(
    last_user=Subquery(
        BatchLogComment.objects.filter(
            batch=OuterRef('pk')
        ).order_by('-created_at').values('user')[:1]
    )
).filter(
    ~Q(last_user=self.request.user),
    comments__user=self.request.user
)
context=None
batch = Batch.objects.filter(comments__user_id=request.user.id).distinct()
batchlogcomment = BatchLogComment.objects.filter(batch__in=a)
c = BatchLogComment.last()
if c.user != request.user:
    context.update({'c':c})

first i'm getting Batch model objects that it's comments associated with current user

then i'm getting BatchLogComment model objects that is in first query (batch)

then getting the last one of these comments

finally checking if the last comment is not commented by the current user and updating context

Related