Waqas
Waqas

Reputation: 639

Django Search bar with ListView

I am trying to add a search bar to a ListView. When I click search the result show fine but when I click on second page of result I get the whole result.

class LegsIndex(FormMixin, generic.ListView):
    form_class = MyForm
    model = Legs
    paginate_by = 5
    template_name = "legs/legshome.html"

    def get_queryset(self):
        return self.model.objects.published()

    def get_context_data(self, **kwargs):
        context = super(LegsIndex, self).get_context_data(**kwargs)
        return context

    def get(self, request, *args, **kwargs):
        form_class = self.get_form_class()
        self.form = self.get_form(form_class)

        search = request.GET.get('search', None)

        if search:
            self.object_list = self.get_queryset().filter(title__icontains=search)
        else:
            self.object_list = self.get_queryset()

        context = self.get_context_data(object_list=self.object_list, form=self.form)
        return self.render_to_response(context)

What is the proper way of doing this. I need filter these fields in form only if any of them is set, otherwise show all data.

class MyFilterForm(Form):

    search = forms.CharField(widget=forms.TextInput(attrs={'placeholder': 'Looking For ...'}), required=False)
    counties = forms.ModelMultipleChoiceField(queryset=Legs.objects.values_list('country', flat=True).distinct(),
                                              widget=forms.CheckboxSelectMultiple(), required=False)
    cities = forms.ModelMultipleChoiceField(queryset=Legs.objects.values_list('city', flat=True).distinct(),
                                            widget=forms.CheckboxSelectMultiple(), required=False)

    class Meta:
        fields = '__all__'

Upvotes: 2

Views: 4088

Answers (2)

Quentin
Quentin

Reputation: 174

I build a library that solve this problem, the ListView is Searchable and paginable and it doesn't lose query parameter

https://github.com/SchroterQuentin/django-search-listview

Upvotes: 1

ruddra
ruddra

Reputation: 51948

From Comments section of the question:

You can simple pass the request from view to form and update it like this:

#View
class LegsIndex(FormMixin, generic.ListView):
     ....
     def get_form_kwargs(self):
        kwargs = super().get_form_kwargs()
        kwargs.update(request_data=self.request)
        return kwargs


#Form
class MyFilterForm(Form):
    #form fields 

     def __init__(self, *args, request_data=None, **kwargs):
        super().__init__(*args, **kwargs)
        self.fields['search'].initial = request_data.GET.get('search', '')

Upvotes: 1

Related Questions