Skip to content

Instantly share code, notes, and snippets.

@pySilver
Last active November 15, 2023 09:39
Show Gist options
  • Save pySilver/6ff2d6fc9488ab20011c86fe18ed638c to your computer and use it in GitHub Desktop.
Save pySilver/6ff2d6fc9488ab20011c86fe18ed638c to your computer and use it in GitHub Desktop.
Integrates wagtail + wagtailmodeladmin + django-filter + django-autocomplete-light
/*
* ===================================================
* django-filter
* ===================================================
*/
.filter-form-header {
padding: 0;
h2 {
background-color: #fafafa;
font-size: 13px;
line-height: 31px;
margin-top: 0;
padding-left: 24px;
border-bottom: 1px solid #e6e6e6;
}
}
.filter-form-body {
border-bottom: 1px solid #e6e6e6;
.filter-form-body--actions {
text-align: right;
}
.radio_select label,
.model_multiple_choice_field label,
.boolean_field label,
.model_choice_field label,
.image_field label {
padding-top: 1.2em;
padding-left: 0;
}
}
{% extends "modeladmin/index.html" %}
{% load i18n %}
{% block content_main %}
{% block filter_form %}
{% if filter %}
<div class="filter-form-header">
<h2>{% trans 'Filter' %}</h2>
</div>
<div class="row filter-form-body">
<div class="col12">
<form action="" method="GET" novalidate>
{{ filter.form.media }}
<div class="row">
<div class="col6">
<ul class="fields">
{% for field in filter.form %}
{% if not forloop.counter|divisibleby:2 %}
{% include "wagtailadmin/shared/field_as_li.html" with field=field %}
{% endif %}
{% endfor %}
</ul>
</div>
<div class="col6">
<ul class="fields">
{% for field in filter.form %}
{% if forloop.counter|divisibleby:2 %}
{% include "wagtailadmin/shared/field_as_li.html" with field=field %}
{% endif %}
{% endfor %}
<li class="filter-form-body--actions">
<input type="submit" value="{% trans 'Filter' %}" class="button"/>
{% if filter.form.cleaned_data %}
<a href="{{ view.index_url }}" class="button no">{% trans 'Reset' %}</a>
{% endif %}
</li>
</ul>
</div>
</div>
</form>
</div>
</div>
{% endif %}
{% endblock %}
{{ block.super }}
{% endblock %}
# wagtail_hooks.py is where you wire your model with wagtailadmin
class ProductAdmin(ModelAdmin):
model = Product
index_view_class = ProductIndexView
list_display = (
"title",
"price",
"brand",
"date_created",
)
# views.py is where custom IndexView is defined
class ProductIndexView(IndexFilterView):
filterset_class = ProductAdminFilterSet
# filtersets.py is where your model filter is defined
from django.utils.translation import gettext_lazy as _
import django_filters
from dal_select2.widgets import ModelSelect2
from .models import Product, Brand
class ProductAdminFilterSet(django_filters.FilterSet):
title = django_filters.CharFilter(label=_("Title"), lookup_expr="icontains")
brand = django_filters.ModelChoiceFilter(
queryset=Brand.objects.all().order_by("title"), widget=ModelSelect2
)
class Meta:
model = Product
fields = ["title", "brand"]
# Generic view which you'll be using for your ModelAdmin.index_view subclassed view.
from django.core.paginator import InvalidPage, Paginator
from wagtail.contrib.modeladmin.views import IndexView as WagtailIndexView
from django_filters.views import FilterMixin
class IndexFilterView(FilterMixin, WagtailIndexView):
def get_queryset(self, request=None):
"""
Base queryset for filterset. Unlike original method from wagtail,
we dont support filtering and searching here
"""
request = request or self.request
qs = self.get_base_queryset(request)
if not qs.query.select_related:
qs = self.apply_select_related(qs)
# Set ordering.
ordering = self.get_ordering(request, qs)
qs = qs.order_by(*ordering)
return qs
def get_context_data(self, **kwargs):
if (
not self.filterset.is_bound
or self.filterset.is_valid()
or not self.get_strict()
):
queryset = self.filterset.qs
else:
queryset = self.filterset.queryset.none()
paginator = Paginator(queryset, self.items_per_page)
try:
page_obj = paginator.page(self.page_num + 1)
except InvalidPage:
page_obj = paginator.page(1)
context = {
"result_count": queryset.count(),
"paginator": paginator,
"page_obj": page_obj,
"object_list": page_obj.object_list,
"show_search": False,
}
context.update(kwargs)
return super().get_context_data(**context)
def get(self, request, *args, **kwargs):
filterset_class = self.get_filterset_class()
self.filterset = self.get_filterset(filterset_class)
context = self.get_context_data(filter=self.filterset)
# Supress default filters
self.filter_specs = []
self.has_filters = False
return self.render_to_response(context)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment