2014-11-03 2 views
0

Я хотел бы иметь что-то вроде этогоКак получить количество элементов, сгруппированных по свойству промежуточной модели

Adventure() | Sci-fi()

которые являются книгами в книжном магазине, связанными по местной цене.

Скажем, Хоббит составляет 5 долларов США в Амазонке и 6 долларов в Барнсе. Поэтому, если бы я перечислял книги в Amazon, у меня будет Adventure (1) как количество книг с определенной ценой на амазонке.

Если я, как это я получаю правильные Жанры:

for u in Bookshop.objects.get(pk=1).BookBookshopLink_set.all(): 
    print u.book.genre 

, который будет печатать, например:

Sci-fi 
Sci-fi 
Adventure 

Здесь находятся модели:

from parler.models import TranslatableModel, TranslatedFields 
from parler.managers import TranslationManager 

class Genre(TranslatableModel): 
    translations = TranslatedFields(
     name=models.CharField(max_length=200), 
     slug=models.SlugField(), 
     description=models.TextField(blank=True), 
     meta={'unique_together': [('language_code', 'slug')]}, 
    ) 

    published = models.BooleanField(default=False) 


class Book(TranslatableModel): 
    translations = TranslatedFields(
     name=models.CharField(max_length=200), 
     slug=models.SlugField(), 
     description=models.TextField(blank=True), 
     meta={'unique_together': [('language_code', 'slug')]}, 
    ) 

    genre = models.ForeignKey(Genre, blank=True, null=True) 
    published = models.BooleanField(default=False) 


class Bookshop(TranslatableModel): 
    translations = TranslatedFields(
     name=models.CharField(max_length=200), 
     description=models.TextField(_('Description'), default='', blank=True), 
     slug=models.SlugField(), 
     meta={'unique_together': [('slug', 'language_code')]}, 
    ) 

    booklist = models.ManyToManyField(Book, blank=True, through='BookBookshopLink') 


class BookBookshopLink(TranslatableModel): 
    bookshop = models.ForeignKey(Bookshop) 
    book = models.ForeignKey(Book) 
    price = models.IntegerField(blank=True, null=True) 

ответ

0

Это перебирает все ваши жанры и печатает, сколько из них есть. Даже если в жанре есть 0.

for a_genre in Gendre.objects.all(): 
    print Book.objects.filter(genre=a_genre).count() 

и если вы хотите его напечатанным с жанровой aswel

for a_genre in Gendre.objects.all(): 
    print "%s (%d)" % (a_genre, Book.objects.filter(genre=a_genre).count()) 

документации для фильтров в Джанго: https://docs.djangoproject.com/en/1.7/topics/db/queries/#retrieving-specific-objects-with-filters

+0

тогда не ваши примеры генерируют 1 запрос в каждом цикле? скажем, у меня 50 жанров, это будет 50 дополнительных запросов. –

1

Для того, чтобы сделать то, что вы пытаетесь достичь в один запрос, вам необходимо использовать Count, annotate и values_list

я покажу вам пример кода, а затем я попытаюсь объяснить:

from django.db.models import Count 
from your_project.models import * 

Genre.objects.all().values_list('name').annotate(num_books=Count('book')) 
  1. .values_list('name'): Это возвращает список всех жанров по имени
  2. .annotate(num_books=Count('book')): Это количество книг для каждого Genre

у меня есть аналогичные структуры модели в своих проектах и ​​когда я исполню этот код, я получаю это как ответ:

[(u'GENRE_NAME', 13), (u'GENRE_NAME', 14), (u'GENRE_NAME', 0),...] 

Вы можете разобрать вывод этого запроса, чтобы соответствовать вашим ожиданиям

Я также рекомендую вам проверить документацию официально Django Agreggation

+0

Действительно, ваше решение работает на 1 уровень глубины. Моя проблема заключается в том, что он должен считать книги, которые присваиваются книжному магазину с помощью модели BookBookshopLink. Спасибо за вход. –

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