Django: запрос комментариев на основе поля объекта - PullRequest
0 голосов
/ 23 февраля 2012

Я использую встроенную систему комментариев Django, которая прекрасно работает. На определенной странице мне нужно перечислить последние X комментариев, которые я только что получил:

latest_comments =   
Comment.objects.filter(is_public=True, is_removed=False)  
.order_by('submit_date').reverse()[:5]

Однако я теперь ввел логическое поле «опубликовано» в родительский объект комментариев, и я хочу включить это в запрос выше. Я пытался использовать поля content_type и object_pk, но на самом деле я ничего не получаю. Обычно вы делаете что-то вроде:

Comment.objects.filter(blogPost__published=True)

Но так как он не хранится таким образом, я не уверен, что делать дальше.

Ответы [ 3 ]

1 голос
/ 23 февраля 2012
posts_ids = BlogPost.objects.filter(is_published=True).values_list('id', flat=True) #return [3,4,5,...]
ctype = ContentType.objects.get_for_model(BlogPost)
latest_comments = Comment.objects.filter(is_public=True, is_removed=False, content_type=ctype, content_object__in=posts_ids).order_by('-submit_date')[:5]
0 голосов
/ 23 февраля 2012

Вы просто не можете сделать это в одном запросе. Комментарии используют GenericForeignKey. Документация гласит:

Из-за способа реализации GenericForeignKey вы не можете использовать такие поля напрямую с фильтрами (например, filter () и exclude ()) через API базы данных.

0 голосов
/ 23 февраля 2012

Комментарии используют GenericForeignKey для хранения отношения к родительскому объекту. Из-за способа работы родовых отношений связанные поиски с использованием синтаксиса __<field> не поддерживаются.

Вы можете выполнить желаемое поведение с помощью поиска «in», однако это потребует большого количества сравнений, когда будет много BlogPosts.

ids = BlogPost.objects.filter(published=True).values_list('id', flat=True) # Get list of ids, you would probably want to limit number of items returned here
content_type = ContentType.objects.get_for_model(BlogPost) # Becasue we filter only comments for BlogPost
latest_comments = Comment.objects.filter(content_type=content_type, object_pk__in=ids,  is_public=True, is_removed=False, ).order_by('submit_date').reverse()[:5]

См. Комментарий модели документ для описания всех полей.

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