I want to know if it is possible not to show/load my Product model when viewing a template. Instead, I want to display my model on click a button that filters the results before displaying them.
I have more than 30,000 records in my Product model and that is why I don't want them to show/load when viewing my template, I know that the paginate_by = '100' method exists, but I find it more useful to filter the records before displaying them
Note: I already have the function and class to filter my Product model records
class barcodeview(ListView):
template_name = "barcode/table.html"
paginate_by = '500'
model= Product
context_object_name = 'product'
# Queryset for filtering product model
def get_queryset(self):
queryset = Product.objects.barcode_filter(
filtr = self.request.GET.get("filtr", ''),
)
return queryset
CodePudding user response:
Put your filter form in your template and only output models when the form is submitted.
Template:
<form method="get">
<input ...>
<button type="submit" name="filter">Filter</button>
</form>
view:
class BarCodeView(ListViw):
def get_queryset(self):
if 'filter' not in self.request.GET:
return self.model.objects.none()
filter_form = FilterForm(self.queryset.GET)
if not filter_form.is_valid():
return self.model.objects.none()
qs = super().get_queryset()
if filter_form.cleaned_data['some_filter_field']:
qs = qs.filter(some_field=filter_form.cleaned_data['some_filter_field']
# more filters if your need
...
return qs
You can adapt this to your needs. The filtering can also be done on the form:
class FilterForm(forms.Form):
some_filter_field = forms.ChoieField(...)
def filter(self, qs):
"""Method added to the original django form, you
will not find it in the documentation"""
if self.cleaned_data['some_filter_field']:
qs = qs.filter(....)
return qs
class BarCodeView(ListView):
def get_queryset(self):
if 'filter' in self.request.GET:
return self.model.none()
form = FilterForm(self.request.GET)
if form.is_valid():
return form.filter(self.model.objects.all())
return self.model.none()
Those aren't the only ways of doing it, but you got the point.