Django | Aggregate Values from Foreign Key - python

I have two databases, A and B.
B contains a ForeignKey to A.
When I do B.objects.filter(a_id=3).values('bags').count(), I get the number I want, Y.
What is the set of commands I need in order to add this number, Y, as an annotation into database A?
Ideally, this would be an annotate type of command.
The models look like:
class A(models.Model):
name = models.CharField(max_length=150)
class B(models.Model):
name = models.CharField(max_length=150)
a_id = models.ForeignKey(A, on_delete=models.CASCADE)
bags = models.ManyToManyField(Bags)
class Bags(models.Model):
name = models.CharField(max_length=150)

Try to use b__bags lookup in annotation:
from django.db.models import Count
A.objects.annotate(bags_count=Count('b__bags'))

from django.db.models import Count
A.objects.annotate(Y=Count('b__bags'))

Related

Django model filter elements

I have four models as follows:
class modelA(models.Model):
name = models.CharField(...)
class modelB(models.Model):
date = models.DateTimeField(...)
A = models.ForeignKey(modelA, ...)
class modelC(models.Model):
email = models.CharField(...)
B = models.ForeignKey(modelB, ...)
class modelD(models.Model):
uid = models.CharField(...)
C = models.ForeignKey(modelC)
Given modelA element id, I have to filter modelD elements based on that id. But I am not sure about how to do that.
I appreciate any ideas!
modalD.objects.filter(C__B__A__name ='name')
when you use double underscore you filter the related Inheritance modal

Reverse query via foreign key and many to many field in Django

What query can I use to return all the Organisation objects that are members of a certain membership_id value?
e.g. return all Organisation objects that have a membership_id = 101
class Organisations(model)
id = models.CharField()
memberships = models.ManyToManyField("self", through="Memberships")
class Memberships(model)
membership_id = models.IntegerField()
organisation_id = models.ForeignKey(Organisations, related_name="orgs",)
Try this:
Organisations.objects.filter(orgs__membership_id=101)

Linear sum of foreign key count django

I have a profile class in my model like follow:
class UserProfile(models.Model):
first_name = ....
....
I two other classes that has foreign key to profile model:
class A(models.Model):
profile = models.ForeignKey(UserProfile)
....
class B(models.Model):
profile = models.ForeignKey(UserProfile)
Now I want to filter active users. I want something like follows. But I don't know how to do it in django!
UserProfile.objects.filter((2*count(A) + count(B))__gte=10).all()
You need to use annotate on the queryset first to run the calculation, then you can filter by it.
from django.db.models import Count
UserProfile.objects.annotate(
score=2*Count('a') + Count('b')
).filter(score__gte=10)

Django how to order by many to many occurences

let's say I have 2 models:
class Recipe(models.Model):
recipe = models.TextField()
ingredients = models.ManyToManyField(Ingredient)
class Ingredient(models.Model):
name = models.CharField()
and I want to know what ingredient is the most used in all the recipes.
How do I query that?
Read about aggregation and annotations at https://docs.djangoproject.com/en/dev/topics/db/aggregation/
To get the name of the most common ingredient:
from django.db.models import Count
most_common = Ingredient.objects.annotate(num_recipes=Count('recipe')).order_by('-num_recipes')[0]
print most_common.name

Distinct in many-to-many relation

class Order(models.Model):
...
class OrderItem(models.Model)
order = models.ForeignKey(Order)
product = models.ForeignKey(Product)
quantity = models.PositiveIntegerField()
What I need to do is to get the Order(s) which has only one order item. How can I write it using the QuerySet objects (without writing SQL)?
The easiest way to do this would be to use the Count aggregation:
from django.db.models import Count
Order.objects.annotate(count = Count('orderitem__id')).filter(count = 1)

Categories