diff --git a/taggit/admin.py b/taggit/admin.py index a9339cfb..2ad04a87 100644 --- a/taggit/admin.py +++ b/taggit/admin.py @@ -1,7 +1,11 @@ from django.contrib import admin - +from django import forms +from django.db import transaction from taggit.models import Tag, TaggedItem +from django.shortcuts import render, redirect +from .forms import MergeTagsForm + class TaggedItemInline(admin.StackedInline): model = TaggedItem @@ -14,3 +18,45 @@ class TagAdmin(admin.ModelAdmin): ordering = ["name", "slug"] search_fields = ["name"] prepopulated_fields = {"slug": ["name"]} + actions = ["merge_tags"] + + def merge_tags(self, request, queryset): + print("🚀 merge_tags called") + print(f"Request method: ✅ {queryset}") + print(f"Request POST data: 😊{request.POST}") + + if request.method == "POST" and "csrfmiddlewaretoken" in request.POST: + form = MergeTagsForm(request.POST) + if request.method == "POST": + print("✅", "after form submission") + new_tag_name = "fruit" # hard coded value of the new tag + new_tag, created = Tag.objects.get_or_create(name=new_tag_name) + with transaction.atomic(): + for tag in queryset: + for tagged_item in tag.taggit_taggeditem_items.all(): + tagged_item.tag = new_tag + tagged_item.save() + # tag.delete() #we can uncomment this to also remove the selected tags + + self.message_user(request, "Tags merged successfully.") + return redirect(request.get_full_path()) + else: + print(f"Form errors: {form.errors}") + self.message_user(request, "Form is invalid.", level="error") + else: + form = MergeTagsForm() + + context = { + "title": "Merge selected tags into a new tag", + "form": form, + "action_checkbox_name": admin.helpers.ACTION_CHECKBOX_NAME, + "queryset": queryset, + } + + return render( + request, + "admin/taggit/merge_tags_form.html", + context, + ) + + merge_tags.short_description = "Merge selected tags" diff --git a/taggit/forms.py b/taggit/forms.py index cd68db6d..08a5c832 100644 --- a/taggit/forms.py +++ b/taggit/forms.py @@ -52,3 +52,11 @@ def has_changed(self, initial_value, data_value): initial_value.sort() return initial_value != data_value + + +class MergeTagsForm(forms.Form): + new_tag_name = forms.CharField( + label="New Tag Name", + max_length=255, + widget=forms.TextInput(attrs={"id": "id_new_tag_name"}), + ) diff --git a/taggit/templates/admin/taggit/merge_tags_form.html b/taggit/templates/admin/taggit/merge_tags_form.html new file mode 100644 index 00000000..a9aa89da --- /dev/null +++ b/taggit/templates/admin/taggit/merge_tags_form.html @@ -0,0 +1,29 @@ +{% extends "admin/base_site.html" %} +{% load i18n admin_urls %} + +{% block title %}{% trans 'Django site admin' %}{% endblock %} + +{% block content %} +
+
+ {% csrf_token %} + {% for field in form %} +
+ {{ field.label_tag }} + {{ field }} + {% if field.errors %} +
    + {% for error in field.errors %} +
  • {{ error }}
  • + {% endfor %} +
+ {% endif %} +
+ {% endfor %} +
+ + +
+
+
+{% endblock %} \ No newline at end of file