ListView и get_queryset с двумя моделями
У меня есть 2 модели, в которых мне нужно выполнить поиск:
class Movies(models.Model):
title = models.CharField(max_length=100)
class Meta:
db_table = "movies"
def __str__(self):
return self.title
class Actors(models.Model):
name = models.CharField(max_length=100)
movies = models.ManyToManyField(Movies, related_name="actors")
class Meta:
db_table = "actors"
def __str__(self):
return self.name
У меня есть форма поиска и мне нужно искать по названию фильма и имени актера. Я знаю как сделать вид для поиска в одной модели:
class SearchView(ListView):
template_name = "search_results.html"
model = Actors
def get_queryset(self):
query = self.request.GET.get('q')
object_list = Actors.objects.filter(name__icontains=query)
return object_list
Но как сделать, когда я хочу искать в двух моделях? В результате в шаблоне должны быть перечислены отдельно вхождения в имена актеров и вхождения в названия фильмов. Как легко обновить мой View?
Я пытался добавить метод get_context_data для расширения контекста, но, к сожалению, я не знаю, как получить доступ ко второй модели в get_query-set. Я использую стандартный db.sqlite3.
Большое спасибо!
Вы были на правильном пути с добавлением функции get_context_data, так как в ListView функция get_queryset используется для модели, на которой основано представление списка. Это должно работать для функции get_context_data:
def get_context_data(self,*args,**kwargs):
context = super(SearchView,self).get_context_data(*args,**kwargs)
query = self.request.GET.get('q')
movies = Movies.objects.filter(title__icontains=query)
context['movies_list'] = movies
return context
Затем в вашем шаблоне вы будете обращаться к фильмам по имени контекстной переменной {{ movies_list }}.
Дайте мне знать, если у вас есть какие-либо вопросы.
class SearchView(ListView):
template_name = "search_results.html"
context_object_name = 'actors'
model = Actors
movies = None
def get_queryset(self):
qs = super().get_queryset()
query = self.request.GET.get('q')
if query:
qs= qs.filter(name__icontains=query)
movies = Movie.objects.filter(title__icontains=query).all()
if movies:
self.movies = movies
return qs
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['movies'] = self.movies
return context