-
Здравствуйте,
Я в django, да и в python новичок, поэтому хотел спросить, правильно ли делать например так:
Т.е. что бы при изменении кол-ва коментариев топика, изменялось и количество коментариев категории.class Category(models.Model):
content_type = models.ForeignKey(ContentType)
object_pk = models.IntegerField()
content_object = generic.GenericForeignKey(ct_field="content_type", fk_field="object_pk")
comments_count = models.IntegerField(blank=True, default=0)
topics_count = models.IntegerField(blank=True, default=0)
title = models.CharField(max_length=255)
desc = models.CharField(max_length=500)
class Topic(models.Model):
category = models.ForeignKey(Category)
title = models.CharField(max_length=255)
desc = models.CharField(max_length=500)
content = models.CharField(max_length=1000)
_comments_count = models.IntegerField(blank=True, default=0, db_column='comments_count')
@property
def comments_count(self):
return self._comments_count
@comments_count.setter
def comments_count(self, value):
self.category.comments_count = self.category.comments_count + value - self._comments_count
self.category.save()
self._comments_count = value -
Java? :-)
Нет, в Питоне такие вещи не приняты. То, что вы хотите, в Джанге лучше выразить так:
from django.db.models import Sum class Category(models.Model): comment_count = models.IntegerField(blank=True, default=0) def update_comment_count(self): aggregate = self.comment_set.aggregate(Sum('comment_count')) self.comment_count = aggregate['comment_count__sum'] self.save() class Topic(models.Model): category = models.ForeignKey(Category) comment_count = models.IntegerField(blank=True, default=0, db_column='comments_count') def save(self, **kwargs): super(Topic, self).save(**kwargs) self.category.update_comment_count()То есть:
- неявная обработка на присваивание обычно не приветствуется, особенно такая нетривиальная: она не только лезет в базу, а ещё и меняет её
- пересчётом своих данных занимается категория, а не её топик, топик только явно сигналит наверх
- пересчёт происходит на момент сохранения топика, потому что джанговский ORM не строится из предположения, что всё меняется мгновенно, глобально и неявно, он всегда требует явных действий для изменения данных
- пересчёт всегда идёт полностью, а не инкрементально, иначе вы попадаете на проблемы с race-condition'ами
-
Спасибо, так действительно намного красивее получается.
Внимание! Это довольно старый топик, посты в него не попадут в новые, и их никто не увидит. Пишите пост, если хотите просто дополнить топик, а чтобы задать новый вопрос — начните новый.
