django_filter, integrate form in classview

I have a Listview class that show a table (working), I also have a django_filter for filtering the table (working).

I want a button in template Listview , that open the django_filter_form ( not working, only show submit buttom), how do that ?

views.py

from django.shortcuts import render
from django.views.generic import ListView
from django.views.generic.edit import FormView
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger

from .models import Cmsexport
from .filters import CmsFilter

from django.contrib.auth.decorators import login_required

class Cms(ListView):
    queryset = Cmsexport.objects.all().values()
    model = Cmsexport
    template_name = 'table.html'
    context_object_name = 'cms'
    paginate_by = 10

    def get_queryset(self):
        queryset = super().get_queryset()
        self.filterset = CmsFilter(self.request.GET, queryset=queryset)

        return self.filterset.qs

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['form'] = self.filterset.form

        return context

filters.py:

from django_filters import FilterSet

from .models import Cmsexport

class CmsFilter(FilterSet):
    class Meta:
        model = Cmsexport
        fields = {
                'name': ['icontains'],
                'state_text': ['icontains'],
                'is_virtual': ['icontains'],
        }

urls.py:

from django.urls import path

from django.views.generic import TemplateView
from . import views
from .views import Cms

urlpatterns = [
    path('', views.dashboard, name='dashboard'),
    path('table/', views.table_view, name='table_view'),
    path('cms/', Cms.as_view(), name='cms'),
    path('filters_form/', TemplateView.as_view(template_name='filters_form.html'), name='filters_form'),
    path('search/', views.search, name='search'),
]

template/table.html:

{% extends 'base.html' %}
{% load crispy_forms_filters %}
{% load crispy_forms_tags %}

{% block content %}
{% include 'filters_form.html' %}
<a href="{% url 'filters_form' %}">Search</a>
   <table class="table table-striped">
        <thead>
            <tr>
                {% for item in object_list %}
                    {% for header in item.keys %}
                        <th>{{ header }}</th>
                    {% endfor %}
                {% endfor %}
            </tr>
        </thead>

        <tbody>
            {% for item in object_list %}
                <tr>
                    {% for value in item.values %}
                        <td>{{ value }}</td>
                    {% endfor %}
                </tr>
            {% endfor %}
        </tbody>
    </table>
...

template/filters_form.html:

{% load crispy_forms_filters %}
{% load crispy_forms_tags %}

<form method="GET">
{% csrf_token %}
{{ form|crispy }}
<button type="submit" class="btn btn-primary">Search</button>
</form>

Regards,

I’m not understanding what you’re asking for here. Can you be more explicit about what you’re trying to do or what the problem is?

I think you want a button to show or hide the filters in your templates where you are rendering all the list values. If so then luckily I’ve done something similar to it
In object_list.html, I’ve this button to show/hide filter

        <h3>
            <i class="mdi mdi-filter text-info" onclick="show_hide_filter();" type="button"></i>
        </h3>

        <div>
            {% include 'parts/inner/filter.html' %}
        </div>

here is the other related code filter.html

{% load static %}
{% load crispy_forms_tags %}

<form class="forms-sample" id="filter_form">
    <input type="hidden" name="page" value="1" id="page_no">
    <input type="hidden" name="show-filter"
    {% if show_filter %}
     value="{{show_filter}}"
     {% else %}
     value=""
     {% endif %}
      id="is_show">

    <div class="row" id="filter_field">
       
        {{ filter.form|crispy }}
    </div>
    <button type="submit" class="btn btn-inverse-primary mr-2">Submit</button>
    <a href=".?show-filter=true" class="btn btn-inverse-dark">Clear</a>
</form>

<script>
    let filter_field = document.getElementById('filter_field')
    let all_select = document.getElementsByTagName('select')
    let form_group = filter_field.getElementsByClassName('form-group')
    let filter_box = document.getElementById("filter_box")

    for (let i of all_select){
        i.classList.add('form-control-sm')
        let first_elm = i.getElementsByTagName("option")

        first_elm[0].innerHTML = "Select"
    }

    for (let i=0; i<form_group.length; i++){
        form_group[i].classList.add('col-md-4')
    }
</script>

{% if not show_filter %}
<script>
    filter_box.style.display = "none"
</script>

{% endif %}

<script>
    

    let is_show = document.getElementById("is_show")

    function show_hide_filter(){

        if (filter_box.style.display == 'none'){
            filter_box.style.display = ''
            is_show.value = "true"
        }
        else{
            filter_box.style.display = "none"
            is_show.value = ""
        }

    }
</script>

here is views.py


class ObjectListView(ListView):
    ....
    ....

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['filter'] = self.get_filter_data()
        context['show_filter'] = self.request.GET.get("show-filter", None)
        return context

    ....
    ....