#python #django
#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:
Вам нужно указать Django, как перейти к полю, содержащему содержимое, которое вы хотите найти. В этом случае исходным полем является tags
и вызывается поле в целевой модели tag
, и вы объединяетесь с помощью синтаксиса двойного подчеркивания. Итак:
qs = qs.filter(tags__tag__icontains=search)