Фильтр Django возвращает много значений - PullRequest
1 голос
/ 13 сентября 2011

Я новичок в django, и я думаю, что это простой вопрос -

У меня есть промежуточный класс, который закодирован следующим образом -

class Link_Book_Course(models.Model):
    book = models.ForeignKey(Book)
    course = models.ForeignKey(Course)
    image = models.CharField(max_length = 200, null=True)
    rating = models.CharField(max_length = 200,null=True)
    def __unicode__(self):
        return self.title
    def save(self):
        self.date_created = datetime.now()
        super(Link_Book_Course,self).save()

Я делаю этот вызовтак как мне бы хотелось, чтобы все авторы книг (Book - еще одна модель с автором в качестве CharField)

    storeOfAuthorNames = Link_Book_Course.objects.filter(book__author)

Однако он не возвращает набор запросов всех авторов.фактически выдает ошибку.

Я думаю, это потому, что book__author имеет несколько значений - как я могу получить их все?

Спасибо!

Ответы [ 4 ]

3 голосов
/ 13 сентября 2011

Я не думаю, что вы используете правильный метод набора запросов. filter() фильтрует по своим аргументам - поэтому ожидаемое использование:

poe = Author.objects.get(name='Edgar Allen Poe')
course_books_by_poe = Link_Book_Course.objects.filter(book__author=poe)

Похоже, вы пытаетесь составить список имен всех авторов книг, использованных в определенном курсе (или, может быть, во всех курсах?). Может быть, вы ищете .values() или values_list()?

all_authors_in_courses = Link_Book_Course.objects.values_list(
        'book__author', flat=True
    ).distinct()

( Редактировать : Обновлено согласно предложению @ ftartaggia)

1 голос
/ 13 сентября 2011

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

Если вы хотите, чтобы экземпляры моделей Author были возвращены из django ORM, и вы можете использовать API-интерфейсы агрегирования, вы можете сделать что-то вроде этого:

from django.db.models import Count
Author.objects.annotate(num_books=Count('book')).filter(num_books__gt=1)
0 голосов
/ 13 сентября 2011

Для начала, оператор фильтра фильтрует поле, соответствующее некоторому шаблону. Так что, если у книги есть простой ForeignKey для автора, вы могли бы иметь
storeOfAuthorNames = Link_Book_Course.objects.filter(book__author="Stephen King"), но не только
storeOfAuthorNames = Link_Book_Course.objects.filter(book__author).

Как только вы пройдете через это, я предполагаю, что Book имеет Author как ManyToManyField, а не ForeignKey (потому что у книги может быть несколько авторов, а автор может опубликовать несколько книг?) В этом случае просто filter(book__author="Stephen King") все равно будет недостаточно. Попробуйте Link_Book_Course.objects.filter(book_author__in=myBookObject.author.all())

0 голосов
/ 13 сентября 2011

метод фильтра, который вы пытаетесь использовать, более или менее преобразуется в SQL следующим образом:

SELECT * FROM Link_Book_Course INNER JOIN Book ON (...) WHERE Book.author =;

Итак, как вы видите, у вашего запроса есть неполное условие where.

В любом случае, это не тот запрос, который вы ищете.

Как насчет чего-то вроде (при условии, что автор - это простое текстовое поле Bookи вы хотите, чтобы только авторы книг ссылались из экземпляров Link_Book_Course):

Book.objects.filter (pk__in = Link_Book_Course.objects.all (). values_list ("book", flat = True)). values_list ("автор ", flat = True)

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