Reputation: 11493
I have two tables in a database (that I've created): Entry
and Nation
. Every time a new entry is created, the user has to fill in what Nation it relates to. So an entry has two fields: Content
[a charfield] and Nation
[a foreign key to a Nation]. The thing is, on the homepage of the site, the most popular nations are displayed in order of how many entries they have. It seems inefficient to constantly look up how many foreign keys in the Entry
table relate to each Nation
, so I'm wondering how I can keep a counter. By this I mean, if I create an extra integer field for the Nations, how could I make it so that every time an entry is created, it increments the correct nation by 1, and every time an entry is destroyed, it decreases the correct nation by 1.
Upvotes: 2
Views: 83
Reputation: 24921
You could use the post_save
signal, which is sent at the end of the save()
method.
First, add (as you said) a counter = IntegerField(default=0)
to your Nation
model.
Then, everytime a new Entry
is created, increase that counter.
from django.db.models.signals import post_save
# Your models ...
def increase_nation_counter(instance, created, **kwargs):
if created: # Just increase counter if it's a new Entry
instance.nation.counter += 1
instance.nation.save()
post_save.connect(increase_nation_counter, sender=Entry)
Then, you could sort your Nation
s with a simple query:
Nation.objects.order_by('-counter')
Upvotes: 2
Reputation: 36551
You could use aggregation. That way, your schema stays normalized, and you don't have the possibility of your data being inconsistent. Your problem seems equivalent to one of the examples quoted there. Try this:
from django.db.models import Count
Nation.objects.annotate(num_entries=Count('entry')).order_by('-num_entries')
Upvotes: 2