Added actions to modify tags and correspondents on multiple documents

This commit is contained in:
Jonas Winkler 2018-07-10 15:39:24 +02:00
parent c5b315f518
commit a40737bd0e
3 changed files with 255 additions and 1 deletions

View File

@ -1,8 +1,12 @@
from datetime import datetime from datetime import datetime
from django.conf import settings from django.conf import settings
from django.contrib import admin from django.contrib import admin, messages
from django.contrib.admin import helpers
from django.contrib.admin.utils import model_ngettext
from django.contrib.auth.models import User, Group from django.contrib.auth.models import User, Group
from django.core.exceptions import PermissionDenied
from django.template.response import TemplateResponse
from django.urls import reverse from django.urls import reverse
from django.templatetags.static import static from django.templatetags.static import static
from django.utils.safestring import mark_safe from django.utils.safestring import mark_safe
@ -132,11 +136,166 @@ class TagAdmin(CommonAdmin):
document.tags.add(obj) document.tags.add(obj)
def add_tag_to_selected(modeladmin, request, queryset):
opts = modeladmin.model._meta
app_label = opts.app_label
if not modeladmin.has_change_permission(request):
raise PermissionDenied
if request.POST.get('post'):
n = queryset.count()
tag = Tag.objects.get(id=request.POST.get('tag_id'))
if n:
for obj in queryset:
obj.tags.add(tag)
obj_display = str(obj)
modeladmin.log_change(request, obj, obj_display)
modeladmin.message_user(request, "Successfully added tag %(tag)s to %(count)d %(items)s." % {
"tag": tag.name, "count": n, "items": model_ngettext(modeladmin.opts, n)
}, messages.SUCCESS)
# Return None to display the change list page again.
return None
title = "Add tag to multiple documents"
context = dict(
modeladmin.admin_site.each_context(request),
title=title,
queryset=queryset,
opts=opts,
action_checkbox_name=helpers.ACTION_CHECKBOX_NAME,
media=modeladmin.media,
action="add_tag_to_selected",
tags=Tag.objects.all()
)
request.current_app = modeladmin.admin_site.name
return TemplateResponse(request,
"admin/%s/%s/mass_modify_tag.html" % (app_label, opts.model_name)
, context)
add_tag_to_selected.short_description = "Add tag to selected documents"
def remove_tag_from_selected(modeladmin, request, queryset):
opts = modeladmin.model._meta
app_label = opts.app_label
if not modeladmin.has_change_permission(request):
raise PermissionDenied
if request.POST.get('post'):
n = queryset.count()
tag = Tag.objects.get(id=request.POST.get('tag_id'))
if n:
for obj in queryset:
obj.tags.remove(tag)
obj_display = str(obj)
modeladmin.log_change(request, obj, obj_display)
modeladmin.message_user(request, "Successfully removed tag %(tag)s from %(count)d %(items)s." % {
"tag": tag.name, "count": n, "items": model_ngettext(modeladmin.opts, n)
}, messages.SUCCESS)
# Return None to display the change list page again.
return None
title = "Remove tag from multiple documents"
context = dict(
modeladmin.admin_site.each_context(request),
title=title,
queryset=queryset,
opts=opts,
action_checkbox_name=helpers.ACTION_CHECKBOX_NAME,
media=modeladmin.media,
action="remove_tag_from_selected",
tags=Tag.objects.all()
)
request.current_app = modeladmin.admin_site.name
return TemplateResponse(request,
"admin/%s/%s/mass_modify_tag.html" % (app_label, opts.model_name)
, context)
remove_tag_from_selected.short_description = "Remove tag from selected documents"
def set_correspondent_on_selected(modeladmin, request, queryset):
opts = modeladmin.model._meta
app_label = opts.app_label
if not modeladmin.has_change_permission(request):
raise PermissionDenied
if request.POST.get('post'):
n = queryset.count()
correspondent = Correspondent.objects.get(id=request.POST.get('correspondent_id'))
if n:
for obj in queryset:
obj_display = str(obj)
modeladmin.log_change(request, obj, obj_display)
queryset.update(correspondent=correspondent)
modeladmin.message_user(request, "Successfully set correspondent %(correspondent)s on %(count)d %(items)s." % {
"correspondent": correspondent.name, "count": n, "items": model_ngettext(modeladmin.opts, n)
}, messages.SUCCESS)
# Return None to display the change list page again.
return None
title = "Set correspondent on multiple documents"
context = dict(
modeladmin.admin_site.each_context(request),
title=title,
queryset=queryset,
opts=opts,
action_checkbox_name=helpers.ACTION_CHECKBOX_NAME,
media=modeladmin.media,
correspondents=Correspondent.objects.all()
)
request.current_app = modeladmin.admin_site.name
return TemplateResponse(request,
"admin/%s/%s/set_correspondent.html" % (app_label, opts.model_name)
, context)
set_correspondent_on_selected.short_description = "Set correspondent on selected documents"
def remove_correspondent_from_selected(modeladmin, request, queryset):
if not modeladmin.has_change_permission(request):
raise PermissionDenied
n = queryset.count()
if n:
for obj in queryset:
obj_display = str(obj)
modeladmin.log_change(request, obj, obj_display)
queryset.update(correspondent=None)
modeladmin.message_user(request, "Successfully removed correspondent from %(count)d %(items)s." % {
"count": n, "items": model_ngettext(modeladmin.opts, n)
}, messages.SUCCESS)
return None
remove_correspondent_from_selected.short_description = "Remove correspondent from selected documents"
class DocumentAdmin(CommonAdmin): class DocumentAdmin(CommonAdmin):
class Media: class Media:
css = { css = {
"all": ("paperless.css",) "all": ("paperless.css",)
} }
search_fields = ("correspondent__name", "title", "content", "tags__name") search_fields = ("correspondent__name", "title", "content", "tags__name")
@ -148,6 +307,9 @@ class DocumentAdmin(CommonAdmin):
ordering = ["-created", "correspondent"] ordering = ["-created", "correspondent"]
actions = [add_tag_to_selected, remove_tag_from_selected, set_correspondent_on_selected, remove_correspondent_from_selected]
def has_add_permission(self, request): def has_add_permission(self, request):
return False return False

View File

@ -0,0 +1,46 @@
{% extends "admin/base_site.html" %}
{% load i18n l10n admin_urls static %}
{% load staticfiles %}
{% block extrahead %}
{{ block.super }}
{{ media }}
<script type="text/javascript" src="{% static 'admin/js/cancel.js' %}"></script>
{% endblock %}
{% block bodyclass %}{{ block.super }} app-{{ opts.app_label }} model-{{ opts.model_name }} delete-confirmation delete-selected-confirmation{% endblock %}
{% block breadcrumbs %}
<div class="breadcrumbs">
<a href="{% url 'admin:index' %}">{% trans 'Home' %}</a>
&rsaquo; <a href="{% url 'admin:app_list' app_label=opts.app_label %}">{{ opts.app_config.verbose_name }}</a>
&rsaquo; <a href="{% url opts|admin_urlname:'changelist' %}">{{ opts.verbose_name_plural|capfirst }}</a>
&rsaquo; {{title}}
</div>
{% endblock %}
{% block content %}
<p>Please select the tag.</p>
<form method="post">{% csrf_token %}
<div>
{% for obj in queryset %}
<input type="hidden" name="{{ action_checkbox_name }}" value="{{ obj.pk|unlocalize }}"/>
{% endfor %}
<p>
<select name="tag_id">
{% for tag in tags %}
<option value="{{tag.id}}">{{tag.name}}</option>
{% endfor %}
</select>
</p>
<input type="hidden" name="action" value="{{action}}"/>
<input type="hidden" name="post" value="yes"/>
<p>
<input type="submit" value="{% trans " Confirm" %}" />
<a href="#" class="button cancel-link">{% trans "Go back" %}</a>
</p>
</div>
</form>
{% endblock %}

View File

@ -0,0 +1,46 @@
{% extends "admin/base_site.html" %}
{% load i18n l10n admin_urls static %}
{% load staticfiles %}
{% block extrahead %}
{{ block.super }}
{{ media }}
<script type="text/javascript" src="{% static 'admin/js/cancel.js' %}"></script>
{% endblock %}
{% block bodyclass %}{{ block.super }} app-{{ opts.app_label }} model-{{ opts.model_name }} delete-confirmation delete-selected-confirmation{% endblock %}
{% block breadcrumbs %}
<div class="breadcrumbs">
<a href="{% url 'admin:index' %}">{% trans 'Home' %}</a>
&rsaquo; <a href="{% url 'admin:app_list' app_label=opts.app_label %}">{{ opts.app_config.verbose_name }}</a>
&rsaquo; <a href="{% url opts|admin_urlname:'changelist' %}">{{ opts.verbose_name_plural|capfirst }}</a>
&rsaquo; {{title}}
</div>
{% endblock %}
{% block content %}
<p>Please select the correspondent.</p>
<form method="post">{% csrf_token %}
<div>
{% for obj in queryset %}
<input type="hidden" name="{{ action_checkbox_name }}" value="{{ obj.pk|unlocalize }}"/>
{% endfor %}
<p>
<select name="correspondent_id">
{% for correspondent in correspondents %}
<option value="{{correspondent.id}}">{{correspondent.name}}</option>
{% endfor %}
</select>
</p>
<input type="hidden" name="action" value="set_correspondent_on_selected"/>
<input type="hidden" name="post" value="yes"/>
<p>
<input type="submit" value="{% trans " Confirm" %}" />
<a href="#" class="button cancel-link">{% trans "Go back" %}</a>
</p>
</div>
</form>
{% endblock %}