James Timmins
James Timmins

Reputation: 25

Joining 2 Django query sets

I have made 2 query sets in django which combine filters and counts and I need to find a way to join them.

The models look like this:

from django.db import models
from django.contrib.auth.models import User

# Create your models here.
class Jokes(models.Model):
    user_id = models.ForeignKey(User, on_delete=models.CASCADE)
    text = models.TextField()
    date = models.DateTimeField()

class Likes(models.Model):
    user_id = models.ForeignKey(User, on_delete=models.CASCADE)
    joke_id = models.ForeignKey(Jokes, on_delete=models.CASCADE)
    dislike = models.BooleanField()

    class Meta:
        unique_together = ('user_id', 'joke_id',)

The queries look like this:

jokeLikes = Likes.objects.filter(dislike = False).select_related('joke_id') 
jokeDislikes = Likes.objects.filter(dislike = True).select_related('joke_id') 
countLikes = jokeLikes.values('joke_id__id', 'joke_id__text').annotate(Count('joke_id__id'))
countDislikes = jokeDislikes.values('joke_id__id','joke_id__text').annotate(Count('joke_id__id'))

I want an output that has this format:

joke_id, joke_text, NumberOfLikes, NumberOfDislikes

Any help is appreciated!

Upvotes: 1

Views: 42

Answers (1)

willeM_ Van Onsem
willeM_ Van Onsem

Reputation: 476557

You can annotate the Jokes object:

from django.db.models import Count, Sum, Value
from django.db.models.functions import Coalesce

Jokes.objects.annotate(
    number_of_likes=Coalesce(Count('likes')-Sum('likes__dislikes'), Value(0)),
    number_of_dislikes=Coalesce(Sum('likes__dislike'), Value(0))
)

This will return a queryset of Jokes for which each Jokes object that arises from this queryset, will have two extra attributes: .number_of_likes, and .number_of_dislikes that contains the number of related likes and dislikes.

Note: normally a Django model is given a singular name, so Joke instead of Jokes, and Like instead of Likes.

Upvotes: 1

Related Questions