mirror of
https://github.com/paperless-ngx/paperless-ngx.git
synced 2025-04-02 13:45:10 -05:00
Added actions to modify tags and correspondents on multiple documents
This commit is contained in:
parent
c5b315f518
commit
a40737bd0e
@ -1,8 +1,12 @@
|
||||
from datetime import datetime
|
||||
|
||||
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.core.exceptions import PermissionDenied
|
||||
from django.template.response import TemplateResponse
|
||||
from django.urls import reverse
|
||||
from django.templatetags.static import static
|
||||
from django.utils.safestring import mark_safe
|
||||
@ -132,11 +136,166 @@ class TagAdmin(CommonAdmin):
|
||||
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 Media:
|
||||
css = {
|
||||
"all": ("paperless.css",)
|
||||
|
||||
}
|
||||
|
||||
search_fields = ("correspondent__name", "title", "content", "tags__name")
|
||||
@ -148,6 +307,9 @@ class DocumentAdmin(CommonAdmin):
|
||||
|
||||
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):
|
||||
return False
|
||||
|
||||
|
46
src/documents/templates/admin/documents/document/mass_modify_tag.html
Executable file
46
src/documents/templates/admin/documents/document/mass_modify_tag.html
Executable 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>
|
||||
› <a href="{% url 'admin:app_list' app_label=opts.app_label %}">{{ opts.app_config.verbose_name }}</a>
|
||||
› <a href="{% url opts|admin_urlname:'changelist' %}">{{ opts.verbose_name_plural|capfirst }}</a>
|
||||
› {{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 %}
|
46
src/documents/templates/admin/documents/document/set_correspondent.html
Executable file
46
src/documents/templates/admin/documents/document/set_correspondent.html
Executable 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>
|
||||
› <a href="{% url 'admin:app_list' app_label=opts.app_label %}">{{ opts.app_config.verbose_name }}</a>
|
||||
› <a href="{% url opts|admin_urlname:'changelist' %}">{{ opts.verbose_name_plural|capfirst }}</a>
|
||||
› {{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 %}
|
Loading…
x
Reference in New Issue
Block a user