2015-01-26 4 views
2

Мне нужно создать запрос в Django, и я чувствую, что немного позади себя, любая помощь является переоцененной. У меня есть содержание и теги, с таблицей отношений между ними:Django: подсчет тегов содержимого, соответствующего запросу

class Content(mixins.TracketEntity): 
    publisher = models.ForeignKey(User) 
    title = models.CharField(max_length=256, null=False, blank=False) 
    data = jsonfield.JSONField() 

class Tag(mixins.TracketEntity): 
    publisher = models.ForeignKey(User) 
    name = models.CharField(max_length=256, null=False, blank=False) 

class ContentTag(models.Model): 
    content = models.ForeignKey(Content) 
    tag = models.ForeignKey(Tag) 

Теперь я могу фильтровать содержимое по названию, например, вот так:

content_query = Content.objects.filter(title__icontains="matematica") 

Это даст список содержимого , говорят:

  • Matematica BASICA
  • Matematica пур
  • Matematica Aplicada
  • Matematica avancada

И сказать это содержание есть эти теги:

  • Matematica BASICA. Метки = MATEMATICA, EASY
  • Matematica pura. Теги = MATEMATICA
  • Matematica aplicada. Теги = MATEMATICA, HARD
  • Matematica avancada. Теги = Matematica, жесткий

Учитывая, что сценарий, как я построить запрос Django, который будет возвращать список тэгов, связанных с содержанием content_query, наряду с графом содержания каждого из них? Ожидаемый набор результатов для этого запроса будет:

  • Matematica, 4
  • ЛЕГКО, 1
  • ЖЕСТКИЙ, 2

Кроме того, этот вид запроса будет выбежала все время в базе данных (Postgres). Какие индексы я должен добавить в базу данных, чтобы заставить ее действовать прилично?

+0

Я обновил свой ответ. – levi

ответ

1

Фактически вы можете просто сделать это в одном запросе посредством агрегации.

from django.db.models import Count 
tags = Tag.objects.filter(content__title__icontains='matematica').values('name').annotate(tag_count=Count('tag')) 

Для того, чтобы сделать эту работу, вам нужно добавить объявление ManyToMany на категории, которая использует существующую через таблицу, ContentTag:

content = models.ManyToManyField('Content', through='ContentTag') 

Поскольку через таблица уже существует, то это не будет вообще измените свою базу данных.

+0

Спасибо, миллион. Ты просто спас наш день сэр :-) –

0

Получить все теги, связанные с Content экземпляров, название содержит "Matematica"

tags = Content.objects.filter(title__icontains="matematica").tags.all() 

Затем подсчет меток.

result_dict = {} 
for tag in tags: 
    result_dict[tag.name] +=1 
Смежные вопросы