基于外键的过滤

Filter based on foreign key

所以我已经在这个问题上工作了很多天,但无法解决。基本上我有三个型号

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()

并且不知道如何过滤其余部分

您可以使用双下划线 ('__') 过滤相关模型的内容,因此您可以过滤 year 关系的 year 属性BookAuthor:

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

.distinct() 很有用,否则在 2018 年出版多本书的 Author 将在查询集中出现 多次 次。

话虽这么说,在这里构建一个 Year 对象似乎很奇怪,而将其设为 CharField 就更奇怪了(因为按 year 排序将导致排序 *按词典顺序)。 Author 模型中的 num 字段可能也应该是 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>

在这种情况下,我们可以查询 Authors 谁在 2018 年出版了一本书:

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

然而,num 在这里做什么还不清楚。如果它包含书籍数量,那么使用 .annotate(..) 可能是更好的选择,因为它避免了数据重复。

可以看出年份是一个CharField,所以必须用引号来查询,必须用lookup(year__year)来查询相关模型中的字段。

authors = Book.objects.filter(year__year='2018').values('author').distinct()