Django CBV and filter by "q" mixin

This is only a short post about combining a CBV with a mixin to support searching by GET param "q" in general. This is often very useful for implementing a search based on some text.

{# post_list.html #}

{% extends 'layouts/backend.html' %}
{% load i18n %}

{% block body %}
    <div class="row">
        <div class="col-md-6">
            <form id="omni-form" action="{% url 'post_list' %}" method="GET" class="form-inline" role="form">
                <div class="input-group">
                    <label class="sr-only" for="omnisearch">{% trans 'Search for posts' %}</label>
                    <input type="text" name="q" class="form-control" id="omnisearch"
                        value="{{ q }}"
                        placeholder="{% trans 'Search for posts' %}">

                    <div class="input-group-btn">
                        <button type="submit"
                                onclick="javascript:document.getElementById('omnisearch').value='';"
                                class="btn btn-default">{% trans 'clear' %}</button>
                        <button type="submit" class="btn btn-default">{% trans 'search' %}</button>
                    </div>
                </div>
            </form>
        </div>
    </div>

    {# list rendering as usual #}

{% endblock %}
# views.py
from django.views.generic import ListView


class FilterByQViewMixin(object):
    def get_queryset(self):
        queryset = super(FilterByQViewMixin, self).get_queryset()
        q = self.request.GET.get('q')
        if q:
            queryset = self.filter_by_q(queryset, q)
        return queryset

    def get_context_data(self, **kwargs):
        context_data = super(FilterByQViewMixin, self).get_context_data(**kwargs)
        context_data['q'] = self.request.GET.get('q', '')
        return context_data

    def filter_by_q(self, queryset, q):
        raise NotImplemented('implement for filtering by q parameter')


class PostListView(FilterByQViewMixin, ListView):
    model = Post
    paginate_by = 25

    def filter_by_q(self, queryset, q):
        return queryset.filter(name__icontains=q)

The concrete filter should be done by overwriting the mixin method filter_by_q like in the example:

def filter_by_q(self, queryset, q):
    return queryset.filter(name__icontains=q)