Фильтр на основе внешнего ключа - PullRequest
0 голосов
/ 27 января 2019

Так что я работал над этой проблемой уже много дней и не могу заставить ее работать. В основном у меня есть три модели

class Year(models.Model):
    year = models.CharField()


class Book(models.Model):
     name = models.CharField(
        verbose_name = "Library Name",
        max_length = 255
    )

    author = models.ForeignKey(
        Author,
        on_delete=models.CASCADE
    )

    year = models.ForeignKey(
        Year,
        on_delete=models.CASCADE
    )

class Author(models.Model):
    name = models.CharField(
        verbose_name = "Author's Name",
        max_length = 255
    )

    num = models.CharField(
        max_length = 255,
        default=0
    )

Например, если я пройду 2018 год, я хочу получить всех авторов, опубликовавших книгу в 2018 году. Я пробовал разные запросы, такие как Year.objects.filter(year=2018).filter()

и не знаю, как отфильтровать остальные

Ответы [ 2 ]

0 голосов
/ 27 января 2019

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

authors = Book.objects.filter(year__year='2018').values('author').distinct()
0 голосов
/ 27 января 2019

Вы можете фильтровать содержимое связанной модели, используя двойные подчеркивания ('__'), поэтому вы можете фильтровать по атрибуту year отношения year для Book этого Author :

Author.objects.filter(<b>book__year__year='2018'</b>).distinct()

* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * .distinct() полезно, так как в противном случае Author s, которые опубликовали несколько книг в 2018 году, будут встречаться несколько раз в наборе запросов.

При этом создание здесь Year объекта кажется довольно странным, а сделать его CharField еще более странным (поскольку сортировка по year приведет к сортировке * лексикографически). Поле num в модели Author, вероятно, также должно быть IntegerField [Django-doc] .

Лучшее моделирование может быть:

class Book(models.Model):
     name = models.CharField(
        verbose_name = "Library Name",
        max_length = 255
    )
    author = models.ForeignKey(
        Author,
        on_delete=models.CASCADE
    )
    <b>year = models.IntegerField()</b>

class Author(models.Model):
    name = models.CharField(
        verbose_name = "Author's Name",
        max_length = 255
    )
    <b>num = models.IntegerField(default=0)</b>

В этом случае мы можем запросить Author с, кто опубликовал книгу в 2018 году с:

Author.objects.filter(<b>book__year=2018</b>).distinct()

Однако все еще неясно, что num делает здесь. Если он содержит количество книг, то лучше использовать .annotate(..), поскольку он позволяет избежать дублирования данных.

...