Split url_name template filter into viewname() and validated_viewname()

This commit is contained in:
Jeremy Stretch 2020-06-25 16:50:35 -04:00
parent 6f8f3f98b4
commit 128327b8a3
3 changed files with 26 additions and 10 deletions

View File

@ -9,7 +9,7 @@
<ol class="breadcrumb">
<li><a href="{% url 'dcim:device_list' %}">Devices</a></li>
<li><a href="{{ instance.device.get_absolute_url }}">{{ instance.device }}</a></li>
<li><a href="{% url instance|url_name:"list" %}?device_id={{ instance.device.pk }}">{{ instance|meta:"verbose_name_plural"|bettertitle }}</a></li>
<li><a href="{% url instance|viewname:"list" %}?device_id={{ instance.device.pk }}">{{ instance|meta:"verbose_name_plural"|bettertitle }}</a></li>
<li>{{ instance }}</li>
</ol>
</div>
@ -17,12 +17,12 @@
<div class="pull-right noprint">
{% plugin_buttons instance %}
{% if request.user|can_change:instance %}
<a href="{% url instance|url_name:"edit" pk=instance.pk %}" class="btn btn-warning">
<a href="{% url instance|viewname:"edit" pk=instance.pk %}" class="btn btn-warning">
<span class="fa fa-pencil" aria-hidden="true"></span> Edit
</a>
{% endif %}
{% if request.user|can_delete:instance %}
<a href="{% url instance|url_name:"delete" pk=instance.pk %}" class="btn btn-danger">
<a href="{% url instance|viewname:"delete" pk=instance.pk %}" class="btn btn-danger">
<span class="fa fa-trash" aria-hidden="true"></span> Delete
</a>
{% endif %}
@ -34,7 +34,7 @@
</li>
{% if perms.extras.view_objectchange %}
<li role="presentation"{% if active_tab == 'changelog' %} class="active"{% endif %}>
<a href="{% url instance|url_name:"changelog" pk=instance.pk %}">Change Log</a>
<a href="{% url instance|viewname:"changelog" pk=instance.pk %}">Change Log</a>
</li>
{% endif %}
</ul>

View File

@ -9,10 +9,10 @@
<button type="button" class="btn btn-default" data-toggle="modal" data-target="#tableconfig" title="Configure table"><i class="fa fa-cog"></i> Configure</button>
{% endif %}
{% if permissions.add and 'add' in action_buttons %}
{% add_button content_type.model_class|url_name:"add" %}
{% add_button content_type.model_class|validated_viewname:"add" %}
{% endif %}
{% if permissions.add and 'import' in action_buttons %}
{% import_button content_type.model_class|url_name:"import" %}
{% import_button content_type.model_class|validated_viewname:"import" %}
{% endif %}
{% if 'export' in action_buttons %}
{% export_button content_type %}
@ -21,7 +21,7 @@
<h1>{% block title %}{{ content_type.model_class|meta:"verbose_name_plural"|bettertitle }}{% endblock %}</h1>
<div class="row">
<div class="col-md-{% if filter_form %}9{% else %}12{% endif %}">
{% with bulk_edit_url=content_type.model_class|url_name:"bulk_edit" bulk_delete_url=content_type.model_class|url_name:"bulk_delete" %}
{% with bulk_edit_url=content_type.model_class|validated_viewname:"bulk_edit" bulk_delete_url=content_type.model_class|validated_viewname:"bulk_delete" %}
{% if permissions.change or permissions.delete %}
<form method="post" class="form form-horizontal">
{% csrf_token %}

View File

@ -5,6 +5,7 @@ import re
import yaml
from django import template
from django.conf import settings
from django.urls import NoReverseMatch, reverse
from django.utils.html import strip_tags
from django.utils.safestring import mark_safe
from markdown import markdown
@ -74,11 +75,26 @@ def meta(obj, attr):
@register.filter()
def url_name(model, action):
def viewname(model, action):
"""
Return the URL name for the given model and action, or None if invalid.
Return the view name for the given model and action. Does not perform any validation.
"""
return '{}:{}_{}'.format(model._meta.app_label, model._meta.model_name, action)
return f'{model._meta.app_label}:{model._meta.model_name}_{action}'
@register.filter()
def validated_viewname(model, action):
"""
Return the view name for the given model and action if valid, or None if invalid.
"""
viewname = f'{model._meta.app_label}:{model._meta.model_name}_{action}'
try:
# Validate and return the view name. We don't return the actual URL yet because many of the templates
# are written to pass a name to {% url %}.
reverse(viewname)
return viewname
except NoReverseMatch:
return None
@register.filter()