I have 2 models in which I need to do a search:
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
I have a search form and need to search in Movies title and Actors name. I know how to make view for search in one model:
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
But how to make when I want to search in two models? The result should then list the occurrences in actor names and occurrences in movie titles separately in the template. How to update my View easily?
I tried to add a method get_context_data to extend the context, but unfortunately I don't know how to access the second model in get_query-set. I use default db.sqlite3.
Thank you very much!
CodePudding user response:
You were on the right track with adding a get_context_data function, as in a ListView the get_queryset function is used for model that the list view is based on. This should work for the get_context_data function:
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
Then in your template you would access the movies by the context variable name {{ movies_list }}.
Let me know if you have any questions.
CodePudding user response:
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 = Movies.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
