2013-05-27 3 views
0

Это мои DB-модель:подсчета/фильтрация базы данных-запись на несколько иностранных ключевых отношениях

class Category(models.Model): 
    name = models.CharField(max_length = 20, unique = True) 
    ... 

class Feed(models.Model): 
    title = models.CharField(max_length = 100) 
    category = models.ForeignKey(Category) 
    ... 

class Article(models.Model): 
    title = models.CharField(max_length = 100) 
    read = models.BooleanField(default = False) 
    feed = models.ForeignKey(Feed) 
    ... 

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

Теперь, я хочу создать представление для отображения все категорий с некоторой метаинформацией, например. сколько непрочитанных статей находится в категории x.

Я пытался что-то вроде этого, но ничего не получалось:

categories = Category.objects.filter(feed__article__read=False)\ 
          .annotate(Count('feed__article')) 

Что такое правильный способ извлечь эти данные? Особенно, если я хочу добавить дополнительную информацию, такую ​​как: количество каналов в категории и количество одобренных товаров в одном QuerySet (если возможно) ...

Любые идеи? Спасибо.

EDIT: Так как я не имел ни малейшего представления о том, как «решить» эту проблему, я написал уродливый обходной путь:

result = categories.values_list('name', 
           'feed__title', 
           'feed__article__title', 
           'feed__article__read') 

for i in range(0, len(result)): 

    #if pointer changed to a new category 
    #dump current dict to list and clear dict for the new values 
    if last != result[i][0]: 
     category_list.append(category_info.copy()) 
     category_info.clear() 
     last = result[i][0]   

    if some values None: 
     insert values   
    elif some other values None: 
     insert values 

    else: 

     category_info['name'] = result[i][0] 
     category_info['feed_count'] = category_info.get('feed_count', 0) + 1 
     category_info['all_article_count'] = category_info.get('all_article_count', 0) + 1 
     #if a article has not been read yet 
     if result[i][3] == False: 
      category_info['unread_article_count'] = category_info.get('unread_article_count', 0) + 1 

    #if this category is the last in the result-list 
    if i+1 == len(result): 
     category_list.append(category_info.copy()) 

    i += 1 

Я уверен, что есть более быстрый и красивый способ, чтобы получить эти информация, но по крайней мере я могу с ней работать на данный момент:/

ответ

0

Вы должны пометить эту информацию. Вы должны иметь возможность использовать category.article_count для элементов в наборе запросов, если вы используете запрос ниже.

categories = Category.objects.filter(feed__article__read=False)\ 
         .annotate(article_count=Count('feed__article')) 
+0

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

+0

, конечно, я имел в виду: спасибо за ваш ** ответ **;) – marv

+0

Он должен работать. Item_count будет равен нулю, но категория находится в наборе запросов. – relekang

Смежные вопросы