Skip to content

Commit

Permalink
Tag merging functionality is done
Browse files Browse the repository at this point in the history
- Selected tag ids are appended to url query parameter
- tag ids are store in the session temporaily
- tags are merged into new tag name
- session is cleared of the tag IDs
  • Loading branch information
guel-codes committed Jul 14, 2024
1 parent 24e2d68 commit 0df866d
Show file tree
Hide file tree
Showing 2 changed files with 76 additions and 54 deletions.
80 changes: 51 additions & 29 deletions taggit/admin.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
from django.contrib import admin
from django import forms
from django.db import transaction
from taggit.models import Tag, TaggedItem

from django.http import JsonResponse
from django.shortcuts import render, redirect
from .forms import MergeTagsForm
from taggit.models import Tag, TaggedItem
from django.urls import path


class TaggedItemInline(admin.StackedInline):
Expand All @@ -18,45 +18,67 @@ class TagAdmin(admin.ModelAdmin):
ordering = ["name", "slug"]
search_fields = ["name"]
prepopulated_fields = {"slug": ["name"]}
actions = ["merge_tags"]
actions = ["render_tag_form"]

def get_urls(self):
urls = super().get_urls()
custom_urls = [
path(
"merge-tags/",
self.admin_site.admin_view(self.merge_tags_view),
name="merge_tags",
),
]
return custom_urls + urls

def render_tag_form(self, request, queryset):
selected = request.POST.getlist(admin.helpers.ACTION_CHECKBOX_NAME)
if not selected:
self.message_user(request, "Please select at least one tag.")
return redirect(request.get_full_path())

selected_tag_ids = ",".join(selected)
redirect_url = (
f"{request.get_full_path()}merge-tags/?selected_tags={selected_tag_ids}"
)

return redirect(redirect_url)

def merge_tags_view(self, request):
if request.method == "GET":
selected_tag_ids = request.GET.get("selected_tags", "").split(",")

def merge_tags(self, request, queryset):
print("🚀 merge_tags called")
print(f"Request method: ✅ {queryset}")
print(f"Request POST data: 😊{request.POST}")
# store selected_tag_ids in session data until they are merged
request.session["selected_tag_ids"] = selected_tag_ids
else:
selected_tag_ids = request.session.get("selected_tag_ids", [])

if request.method == "POST" and "csrfmiddlewaretoken" in request.POST:
if request.method == "POST":
form = MergeTagsForm(request.POST)
if request.method == "POST":
print("✅", "after form submission")
new_tag_name = "fruit" # hard coded value of the new tag
if form.is_valid():
new_tag_name = form.cleaned_data["new_tag_name"]
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():
for tag_id in selected_tag_ids:
tag = Tag.objects.get(id=tag_id)
tagged_items = TaggedItem.objects.filter(tag=tag)
for tagged_item in tagged_items:
tagged_item.tag = new_tag
tagged_item.save()
# tag.delete() #we can uncomment this to also remove the selected tags
# tag.delete() #this will delete the selected tags after merge

self.message_user(request, "Tags merged successfully.")
return redirect(request.get_full_path())
# clear the selected_tag_ids from session after merge is complete
request.session.pop("selected_tag_ids", None)
return redirect("..")
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,
"form": MergeTagsForm(),
"selected_tag_ids": selected_tag_ids,
}

return render(
request,
"admin/taggit/merge_tags_form.html",
context,
)
return render(request, "admin/taggit/merge_tags_form.html", context)

merge_tags.short_description = "Merge selected tags"
render_tag_form.short_description = "Merge selected tags"
50 changes: 25 additions & 25 deletions taggit/templates/admin/taggit/merge_tags_form.html
Original file line number Diff line number Diff line change
@@ -1,29 +1,29 @@
{% extends "admin/base_site.html" %}
{% load i18n admin_urls %}

{% block title %}{% trans 'Django site admin' %}{% endblock %}

{% block content %}
<div class="module">
<form method="post" id="merge-tags-form">
{% csrf_token %}
{% for field in form %}
<div class="form-row">
{{ field.label_tag }}
{{ field }}
{% if field.errors %}
<div id="mergeTagsModal">
<div>
<div>
<div>
<form
id="merge-tags-form"
method="post"
action="{% url 'admin:merge_tags' %}"
>
{% csrf_token %} {% for field in form %}
<div>
{{ field.label_tag }} {{ field }} {% if field.errors %}
<ul class="errorlist">
{% for error in field.errors %}
<li>{{ error }}</li>
{% endfor %}
{% for error in field.errors %}
<li>{{ error }}</li>
{% endfor %}
</ul>
{% endif %}
</div>
{% endfor %}
<div class="submit-row">
<!-- <input type="submit" value="Merge Tags" name="apply_merge" /> -->
<button type="submit" class="button">Merge Tags</button>
</div>
</form>
</div>
{% endfor %}

<div>
<button type="submit" class="btn btn-primary">Merge Tags</button>
</div>
</form>
</div>
</div>
</div>
</div>
{% endblock %}

0 comments on commit 0df866d

Please sign in to comment.