Added adminClone view
This commit is contained in:
@@ -0,0 +1,146 @@
|
||||
|
||||
from functools import update_wrapper
|
||||
from django.contrib.admin import ModelAdmin, helpers
|
||||
from django.contrib.admin.utils import unquote
|
||||
from django.utils.functional import lazy
|
||||
from django.forms.models import model_to_dict
|
||||
from django.forms.formsets import all_valid
|
||||
from django.urls import reverse, path
|
||||
from django.core.exceptions import PermissionDenied
|
||||
from django.http import Http404, HttpResponse
|
||||
from django.db.models.fields.files import FieldFile, FileField
|
||||
|
||||
|
||||
class CloneModelAdmin(ModelAdmin):
|
||||
clone_verbose_name = "Clone"
|
||||
change_form_template = 'admin/admin_change_form.html'
|
||||
cloneable_fields = []
|
||||
|
||||
def get_urls(self):
|
||||
|
||||
def wrap(view):
|
||||
def wrapper(*args, **kwargs):
|
||||
return self.admin_site.admin_view(view)(*args, **kwargs)
|
||||
|
||||
wrapper.model_admin = self
|
||||
return update_wrapper(wrapper, view)
|
||||
|
||||
info = self.opts.app_label, self.opts.model_name
|
||||
|
||||
new_urlpatterns = [
|
||||
path(
|
||||
"<path:object_id>/clone/",
|
||||
wrap(self.clone_view),
|
||||
name="%s_%s_clone" % info,
|
||||
),
|
||||
# path("clone/", self.clone_view, name="%s_%s_clone" % info),
|
||||
]
|
||||
|
||||
print(new_urlpatterns)
|
||||
original_urlpatterns = super(CloneModelAdmin, self).get_urls()
|
||||
return original_urlpatterns + new_urlpatterns
|
||||
|
||||
def change_view(self, request, object_id, form_url='', extra_context=None):
|
||||
print(object_id)
|
||||
url = "{0}coord/traveller/{1}/clone/".format(reverse("admin:index"), object_id)
|
||||
url = "/admin/coord/traveller/3/clone/"
|
||||
extra_context = extra_context or {}
|
||||
extra_context.update({
|
||||
'clone_verbose_name': self.clone_verbose_name,
|
||||
'clone_link': url,
|
||||
})
|
||||
print(extra_context)
|
||||
return super(CloneModelAdmin, self).change_view(request, object_id, form_url, extra_context)
|
||||
|
||||
def clone_view(self, request, object_id, form_url='', extra_context=None):
|
||||
if not self.has_add_permission(request):
|
||||
raise PermissionDenied
|
||||
|
||||
original_obj = self.get_object(request, object_id)
|
||||
|
||||
if original_obj is None:
|
||||
raise Http404
|
||||
|
||||
model_form = self.get_form(request)
|
||||
new_obj = self.model()
|
||||
formsets = []
|
||||
|
||||
if False and formsets:
|
||||
|
||||
form = model_form(request.POST, request.FILES)
|
||||
if form.is_valid():
|
||||
new_obj = self.save_form(request, form, change=False)
|
||||
|
||||
prefixes = {}
|
||||
for FormSet, inline in self.get_formsets_with_inlines(request):
|
||||
prefix = FormSet.get_default_prefix()
|
||||
prefixes[prefix] = prefixes.get(prefix, 0) + 1
|
||||
if prefixes[prefix] != 1 or not prefix:
|
||||
prefix = "%s-%s" % (prefix, prefixes[prefix])
|
||||
|
||||
request_files = request.FILES
|
||||
filter_params = {'%s__pk' % original_obj.__class__.__name__.lower(): original_obj.pk}
|
||||
inlined_objs = inline.model.objects.filter(**filter_params)
|
||||
for n, inlined_obj in enumerate(inlined_objs.all()):
|
||||
for field in inlined_obj._meta.fields:
|
||||
if isinstance(field, FileField) and field not in request_files:
|
||||
value = field.value_from_object(inlined_obj)
|
||||
file_field_name = '{}-{}-{}'.format(prefix, n, field.name)
|
||||
request_files.setdefault(file_field_name, value)
|
||||
|
||||
formset = FormSet(data=request.POST, files=request_files,
|
||||
instance=new_obj,
|
||||
save_as_new="_saveasnew" in request.POST, # ????
|
||||
prefix=prefix)
|
||||
formsets.append(formset)
|
||||
|
||||
if all_valid(formsets) and form.is_valid():
|
||||
self.save_model(request, new_obj, form, False)
|
||||
self.save_related(request, form, formsets, False)
|
||||
try:
|
||||
self.log_addition(request, new_obj)
|
||||
except TypeError:
|
||||
# In Django 1.9 we need one more param
|
||||
self.log_addition(request, new_obj, "Cloned object")
|
||||
|
||||
return self.response_add(request, new_obj, None)
|
||||
|
||||
else:
|
||||
for field in self.cloneable_fields:
|
||||
setattr(new_obj, field, getattr(original_obj, field))
|
||||
|
||||
form = model_form(model_to_dict(new_obj))
|
||||
|
||||
admin_form = helpers.AdminForm(
|
||||
form,
|
||||
list(self.get_fieldsets(request)),
|
||||
self.get_prepopulated_fields(request),
|
||||
self.get_readonly_fields(request),
|
||||
model_admin=self
|
||||
)
|
||||
|
||||
media = self.media + admin_form.media
|
||||
|
||||
inline_admin_formsets = self.get_inline_formsets(request, [], [])
|
||||
title = u'{0} {1}'.format(self.clone_verbose_name, original_obj)
|
||||
|
||||
context = {
|
||||
'title': title,
|
||||
'original': title,
|
||||
'adminform': admin_form,
|
||||
'is_popup': "_popup" in getattr(request, 'REQUEST', request.GET),
|
||||
'show_delete': False,
|
||||
'media': media,
|
||||
'inline_admin_formsets': inline_admin_formsets,
|
||||
# 'errors': helpers.AdminErrorList(form, self.get_formsets_with_inlines(request)),
|
||||
'app_label': "coord"
|
||||
}
|
||||
context.update(extra_context or {})
|
||||
|
||||
return self.render_change_form(
|
||||
request,
|
||||
context,
|
||||
form_url=form_url,
|
||||
change=False,
|
||||
add=False
|
||||
)
|
||||
Reference in New Issue
Block a user