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
Вернуться на верх