Include date hierarchy in quick removal links (#218)

* Include date hierarchy in quick removal links

* use date field name in removal link

* reduce diff

* tweak some details

* start adding tests

* use mock without spec :(

it's not easy to instantiate ChangeList, and speccing from
the class means that many attributes are not recognized

* more tests

* more tests

* more checks for generated URLs

* better tags and tests

* compat for tox 4
This commit is contained in:
Éric
2022-12-11 14:44:31 -05:00
committed by GitHub
parent c414c3ad4d
commit 19cbeead58
6 changed files with 197 additions and 21 deletions
@@ -6,9 +6,11 @@
{% if cl.has_filters %}
<div id="changelist-filter">
<h2>{% translate 'Filter' %}</h2>
{% if cl.has_active_filters %}
{% get_admin_interface_active_date_hierarchy cl as active_date_hierarchy %}
{% get_admin_interface_setting "list_filter_removal_links" as list_filter_removal_links %}
{% if list_filter_removal_links %}
{% if cl.has_active_filters %}
{% if list_filter_removal_links %}
{% if active_date_hierarchy %}{% admin_interface_date_hierarchy_removal_link cl active_date_hierarchy %}{% endif %}
{% for spec in cl.filter_specs %}{% admin_interface_filter_removal_link cl spec %}{% endfor %}
<h3 id="changelist-filter-clear">
<a href="{{ cl.clear_all_filters_qs }}">{% translate "Clear all filters" %} &#10006;</a>
@@ -18,7 +20,12 @@
{# Translators: don't translate this, the django catalog already contains it #}
<a href="{{ cl.clear_all_filters_qs }}">&#10006; {% translate "Clear all filters" %}</a>
</h3>
{% endif %}
{% endif %}
{% elif active_date_hierarchy and list_filter_removal_links %}
{% admin_interface_date_hierarchy_removal_link cl active_date_hierarchy %}
<h3 id="changelist-filter-clear">
<a href="{{ cl.clear_all_filters_qs }}">{% translate "Clear all filters" %} &#10006;</a>
</h3>
{% endif %}
{% for spec in cl.filter_specs %}{% admin_list_filter cl spec %}{% endfor %}
</div>
@@ -0,0 +1,3 @@
<div class="changelist-filter-clear"><a href="{{ removal_link }}">
{{ date_label|capfirst }}: <span>{{ date_value|date:date_format|capfirst }}</span>&nbsp;&#10006;
</a></div>
@@ -1,6 +1,5 @@
{% load admin_interface_tags %}
{% if spec.lookup_val or spec.value %}
<div class="changelist-filter-clear"><a href="{% admin_interface_clear_filter_qs cl spec %}">
{{ title|capfirst }}: <span>{{ selected_value }}</span> &#10006;
<div class="changelist-filter-clear"><a href="{{ removal_link }}">
{{ title|capfirst }}: <span>{{ selected_value }}</span>&nbsp;&#10006;
</a></div>
{% endif %}
@@ -1,9 +1,9 @@
import datetime
import hashlib
import re
from django import template
from django.conf import settings
from django.template.loader import get_template
from django.urls import NoReverseMatch, reverse
from django.utils import translation
@@ -93,14 +93,23 @@ def get_admin_interface_nocache():
return hash_string(__version__)
@register.simple_tag()
def admin_interface_clear_filter_qs(changelist, list_filter):
return changelist.get_query_string(remove=list_filter.expected_parameters())
@register.simple_tag(takes_context=False)
def get_admin_interface_active_date_hierarchy(changelist):
date_field = changelist.date_hierarchy
if not date_field:
return
params = changelist.get_filters_params()
# link to clear all filters contains 'date_field__gte',
# only filters with specific year are really active
if f"{date_field}__year" not in params:
return
return date_field
@register.simple_tag()
@register.inclusion_tag("admin_interface/list_filter_removal_link.html")
def admin_interface_filter_removal_link(changelist, list_filter):
template = get_template("admin_interface/list_filter_removal_link.html")
title = list_filter.title
choices = [
choice for choice in list_filter.choices(changelist) if choice.get("selected")
@@ -110,14 +119,46 @@ def admin_interface_filter_removal_link(changelist, list_filter):
except (IndexError, KeyError):
value = "..."
return template.render(
{
"cl": changelist,
"spec": list_filter,
"selected_value": value,
"title": title,
}
)
removal_link = changelist.get_query_string(remove=list_filter.expected_parameters())
return {
"cl": changelist,
"spec": list_filter,
"selected_value": value,
"title": title,
"removal_link": removal_link,
}
@register.inclusion_tag("admin_interface/date_hierarchy_removal_link.html")
def admin_interface_date_hierarchy_removal_link(changelist, date_field):
date_label = changelist.model._meta.get_field(date_field).verbose_name
params = changelist.get_filters_params()
date_params = [p for p in params if p.startswith(date_field)]
date_args = [int(params[f"{date_field}__year"]), 1, 1]
date_format = "Y"
if f"{date_field}__month" in params:
date_args[1] = int(params[f"{date_field}__month"])
date_format = "YEAR_MONTH_FORMAT"
if f"{date_field}__day" in params:
date_args[2] = int(params[f"{date_field}__day"])
date_format = "DATE_FORMAT"
date_value = datetime.date(*date_args)
removal_link = changelist.get_query_string(remove=date_params)
return {
"cl": changelist,
"date_label": date_label,
"date_value": date_value,
"date_format": date_format,
"removal_link": removal_link,
}
@register.simple_tag()