-
Привет всем!
Есть у меня модели:
[code=python]
class Post(models.Model):
title = models.CharField(max_length=40, primary_key=True)
url_title = models.CharField(max_length=40)
author = models.CharField(max_length=20)
date = models.DateTimeField()
text = models.TextField()
short_text = models.TextField()
tags = models.ManyToManyField(Tag)
objects = PostManager()
def __unicode__(self):
return '%s, %s' % (self.title, self.author)
class Meta:
ordering = ['-date']
class Comment(models.Model):
post = models.ForeignKey(Post)
author = models.CharField(max_length=20)
date = models.DateTimeField()
text = models.TextField()
def __unicode__(self):
return '%s, %s, %s' % (self.post, self.author, self.date)
class Meta:
ordering = ['-date']
[/code]
Вопрос такой: как можно добавить в результаты, которые выдаёт конструкция Post.objects.all() количество комментариев в каждом из постов? Т.е. чтобы можно было делать так, как нечто вроде Post.objects.all()[0].comments_count.
Можно конечно поступить просто и тупо: для каждого поста выполнять запрос SELECT COUNT(*) FROM Comment WHERE Comment.post = 'текущий пост' и передавать массив количеств комментариев в каждом посте в шаблон. Но это как-то тупо, и уверен, что есть способ более гибкий и более красивый.
Кто что думает по этому поводу? -
http://www.djangobook.com/en/2.0/chapter10/
Может как по примеру в DjangoBook создать CommentManager? -
Решил как-то так:
[code=python]
def articles(request):
posts = Post.objects.all()
return render_to_response('articles.html', {'posts': posts})
...
{% for item in posts %}
<div class="article-main">
{{ item.short_text|safe }}
<br />
{{ item.comment_set.count }}
</div>
{% endfor %}
[/code] -
Ну и чем это отличается? Либо делайте annotate(x = Count('comment')), либо делайте денормализацию, обновляемую по сигналу.
-
annotate только в SVN-версии вроде. По-крайней мере у меня нету такого метода (latest stable) в Manager. Потому буду использовать то, как показал выше.
-
annotate только в SVN-версии вроде
SVN-версию бояться не надо, тем более что релизы выходят крайне редко.
Потому буду использовать то, как показал выше.
И будете создавать отдельный запрос к каждому посту.
По-крайней мере у меня нету такого метода
Предполагаю что у вас так же, как и с annotate недоступны defer/only в таком случае можно воспользоваться старой конструкцией:
SELECT_SQL = {'comments_count': 'SELECT COUNT(*) FROM comment WHERE comment.post_id = post.id'} class PostManager(models.Manager): def get_query_set(self): qs = super(PostManager, self).get_query_set() qs = qs.extra(select=SELECT_SQL) return qs -
Я таки не удержался от соблазна использовать агрегации. :) (Не нравится мне способ через manager и прямые SQL-запросы.) Поставил себе 1.1 beta. Всем спасибо за хорошие советы.
Внимание! Это довольно старый топик, посты в него не попадут в новые, и их никто не увидит. Пишите пост, если хотите просто дополнить топик, а чтобы задать новый вопрос — начните новый.

