Поиск в базе данных Django, включая ManyToManyField - PullRequest
1 голос
/ 16 апреля 2019

Я совершенно новый 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 голосов
/ 16 апреля 2019

Вам нужно указать Django, как попасть в поле, содержащее контент, который вы хотите найти. В этом случае исходное поле равно tags, а поле целевой модели называется tag, и вы присоединяетесь к синтаксису с двойным подчеркиванием. Итак:

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