You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

217 lines
8.5 KiB

from django.contrib import admin
from django.utils.translation import gettext_lazy as _
from dj_category.admin import BaseCategoryAdmin
from ajaxdatatable.admin import AjaxDatatable
from django.http import JsonResponse
from django.urls import path
from apps.hadis.models import *
from django import forms
from django.db.models import Case, When, Value
@admin.register(HadisCategory)
class HadisCategoryAdmin(BaseCategoryAdmin):
change_form_template = 'admin/hadiscategory/change_form.html'
change_list_template = 'admin/category_index.html'
fields = (
'name', 'source_type', 'category_type' , 'parent', 'is_active', 'order'
)
search_fields = ['name']
def get_form(self, request, obj=None, **kwargs):
form = super().get_form(request, obj, **kwargs)
return form
def get_urls(self):
urls = super().get_urls()
custom_urls = [
path('categories-ajax/hadiscategory/', self.admin_site.admin_view(self.ajax_categories), name='hadiscategory_ajax_categories'),
]
return custom_urls + urls
def get_categories_groupby_language(self, request=None, selected_values=(), is_multiple=False):
print(f'--get_categories_groupby_language-> {selected_values}')
return super().get_categories(request, selected_values, is_multiple)
def ajax_update(self, request):
data = request.POST
src_node = self.model.objects.get(pk=int(data['srcNode']))
other_node = self.model.objects.get(pk=int(data['otherNode']))
print(f'--ajax_update-> {data}')
if src_node.slug in self.base_categories or other_node.slug in self.base_categories:
return JsonResponse({'data': _('This item can not be modifed')}, status=401)
mode = data['hitMode']
if mode == 'over':
src_node.move_to(other_node, 'first-child')
elif mode == 'after':
src_node.move_to(other_node, 'right')
elif mode == 'before':
src_node.move_to(other_node, 'left')
return JsonResponse({'data': 'ok'}, safe=False)
def get_categories(self, request=None, selected_values=(), is_multiple=False):
"""
Override the get_categories method to filter by source_type if provided in the request
"""
categories = super().get_categories(request, selected_values, is_multiple)
# If request has source_type parameter, filter the categories
if request and request.GET.get('source_type'):
source_type = request.GET.get('source_type')
# Filter the categories by source_type
filtered_categories = []
for category in categories:
# If it's a dictionary (serialized category)
if isinstance(category, dict) and category.get('source_type') == source_type:
filtered_categories.append(category)
# If it's a model instance
elif hasattr(category, 'source_type') and getattr(category, 'source_type') == source_type:
filtered_categories.append(category)
return filtered_categories
return categories
def ajax_categories(self, request):
"""
Handle AJAX request for categories with source_type filtering and search
"""
# Get source_type from request
source_type = request.GET.get('source_type')
# Get node_id if provided (for single node data)
node_id = request.GET.get('node_id')
# Get search term if provided
search = request.GET.get('search')
# Get parent level filter if provided
parent_level = request.GET.get('parent_level')
if node_id:
# Return data for a specific node
try:
node = self.model.objects.get(pk=int(node_id))
return JsonResponse({
'id': node.id,
'source_type': node.source_type,
'category_type': node.category_type,
'parent': node.parent_id,
'level': node.level_p # Add the level_p property
})
except self.model.DoesNotExist:
return JsonResponse({'error': 'Node not found'}, status=404)
# Get all categories
queryset = self.model.objects.all()
# Annotate queryset with level_p
queryset = queryset.annotate(
level_pp=Case(
When(parent=None, then=Value(1)),
When(parent__isnull=False, parent__parent=None, then=Value(2)),
default=Value(3),
output_field=models.IntegerField()
)
)
# Filter by source_type if provided
if source_type:
queryset = queryset.filter(source_type=source_type)
# Filter by search term if provided
if search:
queryset = queryset.filter(name__icontains=search)
# Filter by parent_level if provided
if parent_level and parent_level.isdigit():
# Convert to integer
level = int(parent_level)
# Filter categories by level_p
queryset = queryset.filter(level_pp=level)
# Convert queryset to list of dictionaries for JSON response
categories = []
for category in queryset:
categories.append({
'key': category.id,
'title': category.name,
'parent': category.parent_id,
'source_type': category.source_type,
'category_type': category.category_type,
'level': category.level_p,
# Add data property to store additional information
'data': {
'parent': category.parent_id,
'level': category.level_p
}
})
print(f'-categories-->{categories}')
return JsonResponse(categories, safe=False)
def save_model(self, request, obj, form, change):
print(f'SAVE_MODEL CALLED: {request}/ {obj} / {form} / {change}')
print(f'POST DATA: {request.POST}')
# Get the level choice from the form data
level_choice = request.POST.get('level_choice_hidden')
print(f'LEVEL CHOICE: {level_choice}')
# Get the parent from AJAX selection if provided
ajax_parent = request.POST.get('ajax_parent')
if ajax_parent and ajax_parent.isdigit():
# Set the parent for the object
try:
parent_category = self.model.objects.get(pk=int(ajax_parent))
obj.parent = parent_category
# If parent is level 1, inherit its source_type
# if parent_category.level_p == 1 and level_choice == '2':
# obj.source_type = parent_category.source_type
print(f'AJAX PARENT SET: {parent_category.id} - {parent_category.name}')
except self.model.DoesNotExist:
print(f'PARENT CATEGORY NOT FOUND: {ajax_parent}')
# Debug form validation
if form.is_valid():
print("FORM IS VALID")
else:
print(f"FORM ERRORS: {form.errors}")
print(f'---> {obj}')
# Let the parent class handle the save
super().save_model(request, obj, form, change)
# Add a message to trigger tree reload via JavaScript
from django.contrib import messages
messages.success(request, "Category saved successfully. Tree will be reloaded.")
# Set a flag in the request to redirect back to the category index page
request._category_saved = True
def response_add(self, request, obj, post_url_continue=None):
"""
Override to redirect back to the category index page after adding a new category
"""
if hasattr(request, '_category_saved') and request._category_saved:
from django.http import HttpResponseRedirect
from django.urls import reverse
return HttpResponseRedirect(reverse('admin:hadis_hadiscategory_changelist'))
return super().response_add(request, obj, post_url_continue)
def response_change(self, request, obj):
"""
Override to redirect back to the category index page after editing a category
"""
if hasattr(request, '_category_saved') and request._category_saved:
from django.http import HttpResponseRedirect
from django.urls import reverse
return HttpResponseRedirect(reverse('admin:hadis_hadiscategory_changelist'))
return super().response_change(request, obj)