Class Based Views and Django-filter
The example in the official documentation, https://django-filter.readthedocs.org/en/latest/usage.html, is for a function based view. I have researched how to do the same with a class-based view. I implemented the solution by just overwriting the queryset to allow filtering and context to embed the filters in the template. You can see the complete project where I used CBVs and Django filter on my GitHub link.
from tasktreker.todo.models import Todo
import django_filters
class TaskFilter(django_filters.FilterSet):
title = django_filters.CharFilter(lookup_expr='icontains')
description = django_filters.CharFilter(lookup_expr='icontains')
# year_joined = django_filters.NumberFilter(name='date_joined', lookup_expr='year')
# groups = django_filters.ModelMultipleChoiceFilter(queryset=Group.objects.all(),
# widget=forms.CheckboxSelectMultiple)
class Meta:
model = Todo
fields = ['title', 'description', 'client', 'priority', 'status', 'type', 'assigned']
# we only create a TaskBaseView so that we don’t repeat the model, fields and success_url info lines, then we make our
# Task View Classes inherit from both TaskBaseView and the respective Generic View Classes that Django already has for
# doing CRUD operations.
class TaskBaseView(View):
model = Todo
success_url = reverse_lazy('todo:alltodo')
context_object_name = 'tasks'
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
queryset = self.get_queryset()
filter = TaskFilter(self.request.GET, queryset)
context["filter"] = filter
return context
# view to list tasks in the database assigned to task owner/client
class ClientOnlyTasks(LoginRequiredMixin, TaskBaseView, ListView):
template_name = 'todo/client_only_tasks.html'
def get_queryset(self):
queryset = Todo.objects.filter(client__user=self.request.user)
filter = TaskFilter(self.request.GET, queryset)
return filter.qs
<table class="table table-striped">
<thead>
<tr>
<th>Title</th>
<th>Description</th>
<th>Client</th>
<th>Priority</th>
<th>Status</th>
<th>Type</th>
<th>Completion Date</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
{% if tasks %}
{% for task in filter.qs %}
<tr>
<td><a href="{% url 'todo:update_task' task.id %}">{{ task.title }}</a></td>
<td>{{ task.description |truncatechars:40 }}</td>
<td>{{ task.client }}</td>
<td>
<span class="badge badge-primary rounded-pill d-inline">
{{ task.priority }}
</span>
</td>
<td>
<span
class="badge badge-success rounded-pill d-inline">
{{ task.status }}
</span>
</td>
<td>{{ task.type }}</td>
<td>{{ task.datecompleted }}</td>
<td>
<a href="{% url 'todo:task_detail' task.id%}">View</span></a>
</td>
</tr>
{% endfor %}
{% else %}
<tr>
<td colspan="7"><em class="text-muted">No records found!</em></td>
</tr>
{% endif %}
</tbody>
</table>
</div>
</div>
</div>
</div>