17π
You have managers in Django.
Use a customized manager to do creates and maintain the FK relationships.
The manager can update the counts as the sets of children are updated.
If you donβt want to make customized managers, just extend the save
method. Everything you want to do for denormalizing counts and sums can be done in save
.
You donβt need signals. Just extend save
.
10π
I found django-denorm to be useful. It uses database-level triggers instead of signals, but as far as I know, there is also branch based on different approach.
- How do I convert kilometres to degrees in Geodjango/GEOS?
- Django: Generic views based 'as_view()' method
5π
The first approach (signals) has the advantage to loose the coupling between models.
However, signals are somehow more difficult to maintain, because dependencies are less explicit (at least, in my opinion).
If the correctness of the comment count is not so important, you could also think of a cron job that will update it every n minutes.
However, no matter the solution, denormalizing will make maintenance more difficult; for this reason I would try to avoid it as much as possible, resolving instead to using caches or other techniques β for example, using with comments.count as cnt
in templates may improve performance quite a lot.
Then, if everything else fails, and only in that case, think about what could be the best approach for the specific problem.
- Where are the files downloaded using pip stored in virtualenv?
- Django forms give: Select a valid choice. That choice is not one of the available choices
4π
Django offers a great and efficient (though not very known) alternative to counter denormalization.
It will save your many lines of code and itβs really slow since you retrieve the count in the same SQL query.
I will suppose you have these classes:
class BlogEntry(models.Model):
title = models.CharField()
...
class Comment(models.Model):
body = models.TextField()
blog_entry = models.ForeignKey(BlogEntry)
In your views.py, use annotations:
from django.db.models import Count
def blog_entry_list(Request):
blog_entries = BlogEntry.objects.annotate(count=Count('comment_set')).all()
...
And you will have an extra field per each BlogEntry, that contains the count of comments, plus the rest of fields of BlobEntry.
You can use this extra field in the templates too:
{% for blog_entry in blog_entries %}
{{ blog_entry.title }} has {{ blog_entry.count }} comments!
{% endfor %}
This will not only save you coding and maintenance time but it is really efficient (the query takes only a bit longer to be executed).
- Django models β assign id instead of object
- Django database delete specific number of entries
- How to run a Django celery task every 6am and 6pm daily?
- How to get user email with python social auth with facebook and save it
- Getting "This field is required" even though file is uploaded
-1π
Why not just get the set of comments, and find the number of elements, using the count()
method:
count = blog_entry.comment_set.count()
Then you can pass that into your template.
Or, alternative, in the template itself, you can do:
{{ blog_entry.comment_set.count }}
to get the number of comments.