搜索包括ManyToManyField的Django数据库

时间:2019-04-16 08:45:43

标签: python django

我是Django的新手,但已经阅读了select_related和prefetch_related。但是,我无法构建一个可以覆盖OneToMany关系和ManyToMany关系的搜索功能。

我的模特:

class Tag(models.Model):
    tag = models.CharField(max_length=50, blank=False, unique=True)

    def __str__(self):
        return self.tag


class Course(models.Model):
    title = models.CharField(max_length=10)
    description = models.CharField(max_length=200, blank=True, null=True)
    startdate = models.DateTimeField()
    stopdate = models.DateTimeField()
    teacher = models.ForeignKey(
        Teacher, blank=True, null=True, on_delete=models.PROTECT
    )

    tags = models.ManyToManyField(Tag, blank=True)
    classroom = JSONField(default=json.loads("{}"), blank=True, null=True)

    def __str__(self):
        return "[ {0} ] {1}-{2}".format(self.id, self.title, self.description)

    def startdate_custom(self):
        return self.startdate.strftime("%Y-%m-%d")

在我看来,我有一个想要在数据库中的所有列/表(标题,描述,老师,标签,教室)上查询(使用搜索功能)的类。 简化以下示例:

我可以在主表上建立查询:

search = 'Api'
qs = self.model.objects.select_related('teacher').prefetch_related('tags')
qs = qs.filter(description__icontains=search)

此方法适用于标题,说明,老师...但不适用于我的ManyToManyField

但是我不能将过滤器扩展到标签

search = 'Api'
qs = self.model.objects.select_related('teacher').prefetch_related('tags')
qs = qs.filter(tag__icontains=search) <-- does not work

但是,似乎可以通过遍历标签来过滤掉标签:

tags_qs = self.model.objects.all().prefetch_related('tags')
tags_list = [list(course.tags.filter(tag__icontains='API')) for course in tags_qs]

但这似乎会产生标签列表,而我需要所有课程的集合,在标题,说明,教师或标签中都可以找到搜索词。

我是否需要对模型进行2个单独的查询并以某种方式(如何?)将其加入,还是我缺少有关如何查询ManyToMany关系的信息?

1 个答案:

答案 0 :(得分:0)

您需要告诉Django如何进入包含您要搜索的内容的字段。在这种情况下,源字段为tags,目标模型上的字段称为tag,您可以使用双下划线语法进行联接。所以:

qs = qs.filter(tags__tag__icontains=search)