Проблема при попытке присоединиться с помощью `comments` contrib в Django - PullRequest
3 голосов
/ 02 мая 2010

У меня есть эта модель, комментарии обрабатываются с помощью django_comments contrib:

class Fortune(models.Model):
    author = models.CharField(max_length=45, blank=False)
    title = models.CharField(max_length=200, blank=False)
    slug = models.SlugField(_('slug'), db_index=True, max_length=255, unique_for_date='pub_date')
    content = models.TextField(blank=False)
    pub_date = models.DateTimeField(_('published date'), db_index=True, default=datetime.now())
    votes = models.IntegerField(default=0)
    comments = generic.GenericRelation(
        Comment,
        content_type_field='content_type',
        object_id_field='object_pk'
    )

Я хочу получить Fortune объектов с дополнительным значением nb_comments для каждого, считая их количество комментариев; Я пытаюсь этот запрос:

>>> Fortune.objects.annotate(nb_comments=models.Count('comments'))

Из скорлупы:

>>> from django_fortunes.models import Fortune
>>> from django.db.models import Count
>>> Fortune.objects.annotate(nb_comments=Count('comments'))
[<Fortune: My first fortune, from NiKo>, <Fortune: Another One, from Dude>, <Fortune: A funny one, from NiKo>]
>>> from django.db import connection
>>> connection.queries.pop()
{'time': '0.000', 'sql': u'SELECT "django_fortunes_fortune"."id", "django_fortunes_fortune"."author", "django_fortunes_fortune"."title", "django_fortunes_fortune"."slug", "django_fortunes_fortune"."content", "django_fortunes_fortune"."pub_date", "django_fortunes_fortune"."votes", COUNT("django_comments"."id") AS "nb_comments" FROM "django_fortunes_fortune" LEFT OUTER JOIN "django_comments" ON ("django_fortunes_fortune"."id" = "django_comments"."object_pk") GROUP BY "django_fortunes_fortune"."id", "django_fortunes_fortune"."author", "django_fortunes_fortune"."title", "django_fortunes_fortune"."slug", "django_fortunes_fortune"."content", "django_fortunes_fortune"."pub_date", "django_fortunes_fortune"."votes" LIMIT 21'}

Ниже приведен правильно отформатированный SQL-запрос:

SELECT "django_fortunes_fortune"."id", 
       "django_fortunes_fortune"."author", 
       "django_fortunes_fortune"."title", 
       "django_fortunes_fortune"."slug", 
       "django_fortunes_fortune"."content", 
       "django_fortunes_fortune"."pub_date", 
       "django_fortunes_fortune"."votes", 
       COUNT("django_comments"."id") AS "nb_comments" 
FROM "django_fortunes_fortune" 
LEFT OUTER JOIN "django_comments" 
    ON ("django_fortunes_fortune"."id" = "django_comments"."object_pk") 
GROUP BY "django_fortunes_fortune"."id", 
         "django_fortunes_fortune"."author", 
         "django_fortunes_fortune"."title", 
         "django_fortunes_fortune"."slug", 
         "django_fortunes_fortune"."content", 
         "django_fortunes_fortune"."pub_date", 
         "django_fortunes_fortune"."votes" 
LIMIT 21

Можете ли вы определить проблему? Django НЕ СЛЕДУЕТ ПОДКЛЮЧАТЬ К таблице django_comments с данными content_type (которые содержат ссылку на fortune).

Это тот тип запроса, который я бы хотел сгенерировать с помощью ORM:

SELECT "django_fortunes_fortune"."id", 
       "django_fortunes_fortune"."author", 
       "django_fortunes_fortune"."title", 
       COUNT("django_comments"."id") AS "nb_comments" 
FROM "django_fortunes_fortune" 
    LEFT OUTER JOIN "django_comments" 
        ON ("django_fortunes_fortune"."id" = "django_comments"."object_pk") 
    LEFT OUTER JOIN "django_content_type" 
        ON ("django_comments"."content_type_id" = "django_content_type"."id") 
GROUP BY "django_fortunes_fortune"."id", 
         "django_fortunes_fortune"."author", 
         "django_fortunes_fortune"."title", 
         "django_fortunes_fortune"."slug", 
         "django_fortunes_fortune"."content", 
         "django_fortunes_fortune"."pub_date", 
         "django_fortunes_fortune"."votes" 
LIMIT 21

Но мне не удается это сделать, поэтому помощь от ветеранов Джанго была бы очень признательна:)

Подсказка: я использую Django 1.2-DEV

Заранее спасибо за помощь.

Ответы [ 3 ]

2 голосов
/ 02 мая 2010

Это ошибка в Django, см. Тикет # 10870 . Вам придется подождать хотя бы Django 1.3 или починить его самостоятельно.

2 голосов
/ 02 мая 2010

Почему вы хотите присоединиться к таблице типов контента? Исходный запрос неверен, но не по этой причине. Ссылка на тип содержимого указывает, с какой целевой моделью связаны комментарии, но вы уже знаете это, поскольку выбираете только комментарии, связанные с Fortune. Django уже запросит модель ContentType, чтобы получить значение для Fortune, поэтому следует просто добавить одно предложение WHERE:

... WHERE django_comments_comment.content_type_id = xx

Вы могли бы сделать это правильно, добавив эквивалент ORM:

...filter(comment__content_type=ContentType.objects.get_for_model(Fortune))

хотя, похоже, ошибка в том, что Django не делает этого автоматически.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...