I want to make a dynamic filtering form with Django and django-filter like stackoverflow filter
and i want to use this filter on a template that render by DetailView , now the problem is i searched alot and i didn't found example of how to make this happen
in my template i list all 'courses' that related to 'materials' class and i want to make a form on the same template so i can filter this list
my template
{% for course in material_detail.courses_set.all %}
<div class="course">
<h5>{{ course.course_name }}</h5>
<p>{{ course.course_description }} </p>
</div>
<hr/>
{% endfor %}
I have two models 'Materials' and 'Courses' my models.py
class Materials(models.Model):
materials_name = models.CharField(max_length=200)
materials_description = models.CharField(max_length=200, null=True)
slug_material = models.SlugField(blank=True, unique=True)
class Courses(models.Model):
course_name = models.CharField(max_length=200)
course_description = models.CharField(max_length=300, null=True)
material = models.ForeignKey(Materials, on_delete = models.CASCADE)
and i have one Class DetailView my views.py
class MaterialsDetailView(DetailView):
model = Materials
template_name = 'tuts/material.html'
context_object_name = 'material_detail'
I have made a filters.py file and make this code on it , but i don't know how to link this with my Class DetailView
import django_filters
from .models import Materials
class CourseFilter(django_filters.FilterSet):
class Meta:
model = Materials
fields = ['courses__course_name', 'courses__course_description']
Note: there are more code on my models and template i remove it to make the code very simple
You are just displaying the course list related to the material. So you can filter related courses with f = CourseFilter(self.request.GET, queryset=Courses.objects.filter(material=material_pk))
. Notice I m using the CourseFilter
instead of MaterialFilter
views.py
class MaterialsDetailView(DetailView):
model = Materials
template_name = 'tuts/material.html'
context_object_name = 'material_detail'
def get_context_data(self, **kwargs):
context_data = super(MaterialsDetailView, self).get_context_data()
material_pk = self.kwargs.get('pk', None)
f = CourseFilter(self.request.GET, queryset=Courses.objects.filter(material=material_pk))
context_data['filter'] = f
return context_data
filters.py
class CourseFilter(django_filters.FilterSet):
class Meta:
model = Courses
fields = []
course_name = django_filters.CharFilter(field_name="course_name", lookup_expr="icontains")
course_description = django_filters.CharFilter(field_name="course_description", lookup_expr="icontains")
In your template, you can access all your filtered queryset in filter.qs
and the corresponding form in filter.form
tuts/material.html
<form method="GET">
{{ filter.form.as_p }}
<input type="submit" />
</form>
{% for course in filter.qs %}
<div class="course">
<h5>{{ course.course_name }}</h5>
<p>{{ course.course_description }} </p>
</div>
<hr/>
{% endfor %}