def history_view(self, request, object_id, extra_context=None): "The 'history' admin view for this model." from django.contrib.admin.models import LogEntry # First check if the user can see this history. model = self.model obj = get_object_or_404(self.get_queryset(request), pk=unquote(object_id)) if not self.has_change_permission(request, obj): raise PermissionDenied # Then get the history for this object. opts = model._meta app_label = opts.app_label action_list = LogEntry.objects.filter( object_id=unquote(str(obj.identity)), # this is the change for our override; content_type=get_content_type_for_model(model) ).select_related().order_by('action_time') ctx = self.admin_site.each_context(request) context = dict(ctx, title=('Change history: %s') % force_text(obj), action_list=action_list, module_name=capfirst( force_text(opts.verbose_name_plural)), object=obj, opts=opts, preserved_filters=self.get_preserved_filters(request), ) context.update(extra_context or {}) return TemplateResponse(request, self.object_history_template or [ "admin/%s/%s/object_history.html" % (app_label, opts.model_name), "admin/%s/object_history.html" % app_label, "admin/object_history.html" ], context)
def button_view_dispatcher(self, request, url): # Dispatch the url to a function call if url is not None: res = re.match('(.*/)?(?P<id>\d+)/(?P<command>.*)', url) if res: if res.group('command') in [b.func_name for b in self.change_buttons]: obj = self.model._default_manager.get(pk=res.group('id')) response = getattr(self, res.group('command'))(request, obj) if response is None: return HttpResponseRedirect(request.META['HTTP_REFERER']) return response else: res = re.match('(.*/)?(?P<command>.*)', url) if res: if res.group('command') in [b.func_name for b in self.list_buttons]: response = getattr(self, res.group('command'))(request) if response is None: return HttpResponseRedirect(request.META['HTTP_REFERER']) return response # Delegate to the appropriate method, based on the URL. if url is None: return self.changelist_view(request) elif url == 'add': return self.add_view(request) elif url.endswith('/history'): return self.history_view(request, unquote(url[:-8])) elif url.endswith('/delete'): return self.delete_view(request, unquote(url[:-7])) else: return self.change_view(request, unquote(url))
def history_view(self, request, object_id, extra_context=None): "The 'history' admin view for this model." # First check if the object exists and the user can see its history. model = self.model obj = get_object_or_404(model.objects.using(request.database), pk=unquote(object_id)) if not self.has_change_permission(request, obj): raise PermissionDenied # Then get the history for this object. opts = model._meta app_label = opts.app_label action_list = LogEntry.objects.using(request.database).filter( object_id=unquote(object_id), content_type__id__exact=ContentType.objects.get_for_model(model).id ).select_related().order_by('action_time') context = { 'title': capfirst(force_text(opts.verbose_name) + " " + unquote(object_id)), 'action_list': action_list, 'module_name': capfirst(force_text(opts.verbose_name_plural)), 'object': obj, 'app_label': app_label, 'opts': opts, 'active_tab': 'history', 'object_id': object_id, 'model': ContentType.objects.get_for_model(model).model, } context.update(extra_context or {}) return TemplateResponse(request, self.object_history_template or [ "admin/%s/%s/object_history.html" % (app_label, opts.model_name), "admin/%s/object_history.html" % app_label, "admin/object_history.html" ], context, current_app=self.admin_site.name)
def history_view(self, request, page_id, extra_context=None): """Overriding history_view() to use custom LogEntry model.""" model = self.model obj = self.get_object(request, unquote(page_id)) if obj is None: raise Http404(_('{name} with primary key {pk} does not exist.').format( name=force_text(model._meta.verbose_name), pk=escape(page_id) )) if not self.has_change_permission(request, obj): raise PermissionDenied # Then get the history for this object. action_list = LogEntry.objects.filter( page_id=unquote(page_id), ).select_related().order_by('-action_time')[:self.logentry_limit] opts = model._meta context = dict( title=_('History: %s') % force_text(obj), action_list=action_list, module_name=capfirst(force_text(opts.verbose_name_plural)), object=obj, opts=opts, preserved_filters=self.get_preserved_filters(request), ) context.update(extra_context or {}) request.current_app = self.admin_site.name return TemplateResponse(request, self.object_history_template, context)
def ajaxdelete_view(self, request, object_id): "The 'delete' admin view for this model." opts = self.model._meta app_label = opts.app_label obj = self.get_object(request, unquote(object_id)) if not self.has_delete_permission(request, obj): raise PermissionDenied if obj is None: raise Http404( _('%(name)s object with primary key %(key)r does not exist.') % {'name': force_text(opts.verbose_name), 'key': escape(object_id)} ) using = router.db_for_write(self.model) # Populate deleted_objects, a data structure of all related objects that # will also be deleted. (deleted_objects, perms_needed, protected) = get_deleted_objects( [obj], opts, request.user, self.admin_site, using) if perms_needed: return PermissionDenied obj_display = force_text(obj) self.log_deletion(request, obj, obj_display) self.delete_model(request, obj) return HttpResponse('<html><body>OK</body></html>')
def changeform_view(self, request, object_id=None, form_url='', extra_context=None): extra_context = extra_context or {} comment = self.get_object(request, unquote(object_id)) if comment is not None: extra_context['user_agent'] = get_user_agent(comment.user_agent) or truncatechars(comment.user_agent, 60) return super(CommentAdmin, self).changeform_view(request, object_id=object_id, form_url=form_url, extra_context=extra_context)
def history_view(self, request, object_id, extra_context=None): """The 'history' admin view for this model.""" request.current_app = self.admin_site.name model = self.model opts = model._meta app_label = opts.app_label pk_name = opts.pk.attname history = getattr(model, model._meta.simple_history_manager_attribute) object_id = unquote(object_id) action_list = history.filter(**{pk_name: object_id}) # If no history was found, see whether this object even exists. try: obj = model.objects.get(**{pk_name: object_id}) except model.DoesNotExist: try: obj = action_list.latest("history_date").instance except action_list.model.DoesNotExist: raise http.Http404 content_type = ContentType.objects.get_by_natural_key(*USER_NATURAL_KEY) admin_user_view = "admin:%s_%s_change" % (content_type.app_label, content_type.model) context = { "title": _("Change history: %s") % force_text(obj), "action_list": action_list, "module_name": capfirst(force_text(opts.verbose_name_plural)), "object": obj, "root_path": getattr(self.admin_site, "root_path", None), "app_label": app_label, "opts": opts, "admin_user_view": admin_user_view, } context.update(extra_context or {}) return render( request, template_name=self.object_history_template, dictionary=context, current_app=request.current_app )
def delete_view(self, request, object_id, extra_context=None): to_field = request.POST.get(TO_FIELD_VAR, request.GET.get(TO_FIELD_VAR)) # parent raises exception under these conditions before obj is # obtained, so we preserve that ordering here if not (to_field and not self.to_field_allowed(request, to_field)): obj = self.get_object(request, unquote(object_id), to_field) if obj: task_id = obj.task.pk # by calling parent here, we can get the object's associated task # before it is deleted, but let the parent do all necessary # handling and give it an opportunity to generate exceptions parent_response = super().delete_view(request, object_id, extra_context) # request.post means user has confirmed deletion, this is the # response we potentially wish to redirect if request.POST and IS_POPUP_VAR not in request.POST: # Your IDE will warn you that task_id may be referenced before # assignment. This is not possible because the conditions # that would cause task_id not to be assigned would also # cause the parent call to raise an exception return self.redirect_back_to_task(request, task_id) return parent_response
def compare_view(self, request, object_id, version_id, extra_context=None): """Actually compare two versions.""" opts = self.model._meta object_id = unquote(object_id) # get_for_object's ordering means this is always the latest revision. # The reversion we want to compare to current = Version.objects.get_for_object_reference(self.model, object_id)[0] revision = Version.objects.get_for_object_reference(self.model, object_id).filter(id=version_id)[0] the_diff = make_diff(current, revision) context = { "title": _("Comparing current %(model)s with revision created %(date)s") % { 'model': current, 'date' : get_date(revision), }, "opts": opts, "compare_list_url": reverse("%s:%s_%s_comparelist" % (self.admin_site.name, opts.app_label, opts.model_name), args=(quote(object_id),)), "diff_list": the_diff, } extra_context = extra_context or {} context.update(extra_context) return render(request, self.compare_template or self._get_template_list("compare.html"), context)
def delete(request, app_label, model_name, pk, template='wagtailsnippets/snippets/confirm_delete.html', redirect_to=_redirect_to): model = get_snippet_model_from_url_params(app_label, model_name) permission = get_permission_name('delete', model) if not request.user.has_perm(permission): return permission_denied(request) instance = get_object_or_404(model, pk=unquote(pk)) if request.method == 'POST': instance.delete() messages.success( request, _("{snippet_type} '{instance}' deleted.").format( snippet_type=capfirst(model._meta.verbose_name_plural), instance=instance ) ) return redirect_to(app_label, model_name) return render(request, template, { 'model_opts': model._meta, 'instance': instance, })
def show_view(self, request, object_id, form_url='', extra_context=None): model = self.model opts = model._meta obj = self.get_object(request, unquote(object_id)) if not self.has_show_permission(request, obj): raise PermissionDenied if obj is None: raise Http404(_('%(name)s object with primary key %(key)r does not exist.') % { 'name': force_text(opts.verbose_name), 'key': escape(object_id)}) ModelForm = self.get_form(request, obj) form = ModelForm(instance=obj) all_fields = flatten_fieldsets(self.get_fieldsets(request, obj)) adminForm = helpers.AdminForm( form, list(self.get_fieldsets(request, obj)), self.get_prepopulated_fields(request, obj), readonly_fields=all_fields, # All fields readonly model_admin=self) media = self.media + adminForm.media opts = self.model._meta formsets, inline_instances = self._create_formsets(request, obj, change=True) inline_formsets = self.get_show_inline_formsets(request, formsets, inline_instances, obj) for inline_formset in inline_formsets: media = media + inline_formset.media # Show Actions show_actions = self.get_show_actions(request, obj) view_on_site_url = self.get_view_on_site_url(obj) context = dict( self.admin_site.each_context(request), show_actions=show_actions, title=_(u'View {verbose_name}').format( verbose_name=force_unicode(opts.verbose_name)), adminform=adminForm, view_name='show', object_id=object_id, original=obj, is_popup=(IS_POPUP_VAR in request.POST or IS_POPUP_VAR in request.GET), media=media, inline_admin_formsets=inline_formsets, errors=helpers.AdminErrorList(form, []), app_label=opts.app_label, is_show_view=True, has_add_permission=self.has_add_permission(request), has_change_permission=self.has_change_permission(request, obj), has_delete_permission=self.has_delete_permission(request, obj), has_absolute_url=view_on_site_url is not None, absolute_url=view_on_site_url, opts=opts, ) context.update(extra_context or {}) self.log_show(request, obj) return TemplateResponse(request, self.get_show_object_template(), context)
def Comments(request, app, model, object_id): try: modeltype = ContentType.objects.using(request.database).get(app_label=app, model=model) modeltype._state.db = request.database object_id = unquote(object_id) modelinstance = modeltype.get_object_for_this_type(pk=object_id) comments = Comment.objects.using(request.database) \ .filter(content_type__pk=modeltype.id, object_pk=object_id) \ .order_by('-id') except: raise Http404('Object not found') if request.method == 'POST': comment = request.POST['comment'] if comment: Comment( content_object=modelinstance, user=request.user, comment=comment ).save(using=request.database) return HttpResponseRedirect('%s/comments/%s/%s/%s/' % (request.prefix, app, model, object_id)) else: return render_to_response('common/comments.html', { 'title': capfirst(force_text(modelinstance._meta.verbose_name) + " " + object_id), 'model': model, 'object_id': quote(object_id), 'active_tab': 'comments', 'comments': comments }, context_instance=RequestContext(request))
def change_view(self, request, object_id, form_url='', extra_context=None): request.session['lasttab'] = 'edit' new_extra_context = extra_context or {} new_extra_context['title'] = force_text(self.model._meta.verbose_name) + ' ' + unquote(object_id) # Translators: Translation included with Django new_extra_context['post_title'] = _('edit') return super().change_view(request, object_id, form_url, new_extra_context)
def changeform_view(self, request, object_id=None, form_url='', extra_context=None): if request.method == 'POST' and "_searchdatabase" in request.POST: if object_id is None: ModelForm = self.get_form(request, None) form = ModelForm(request.POST, request.FILES, instance=None) if not form.is_valid(): return super(AchatAdmin, self).changeform_view(request, \ object_id, form_url, extra_context) new_object = self.save_form(request, form, change=False) new_object.save() pending = Pending(achat=new_object) pending.save() object_id = new_object.pk post_url = reverse('admin:dbref_association_changelist') post_url += '?' + urllib.parse.urlencode({'achat': object_id}) return HttpResponseRedirect(post_url) if request.method == 'POST' and "_cancel" in request.POST: post_url = reverse('admin:achat_achat_changelist') return HttpResponseRedirect(post_url) if request.method == 'POST' and "_save" in request.POST: if object_id is not None: obj = self.get_object(request, unquote(object_id), None) if hasattr(obj, 'pending'): obj.pending.delete() add = object_id is None title=(_('Add %s') if add else _('Change %s')) % _('purchase record') context = dict(title=title) context.update(extra_context or {}) return super(AchatAdmin, self).changeform_view(request, \ object_id, form_url, context)
def history_view(self, request, object_id, extra_context=None): if not self.has_change_permission(request): raise PermissionDenied object_id = unquote(object_id) active_lang = request.GET.get('language') or get_language() opts = self.model._meta action_list = [ { "revision": version.revision, "url": reverse("%s:%s_%s_revision" % ( self.admin_site.name, opts.app_label, opts.model_name), args=(quote(version.object_id), version.id)), } for version in self._order_version_queryset( self.revision_manager.get_for_object_reference( self.model, object_id, ).select_related("revision__user")) if simplejson.loads(version.serialized_data)[0]['fields'].get( 'language_code' ) == active_lang ] context = {"action_list": action_list} context.update(extra_context or {}) return super().history_view(request, object_id, context)
def change_view(self, request, object_id, form_url='', extra_context=None): """ Override this function to hide the sumbit row from the user who has view only permission """ model = self.model opts = model._meta if object_id: obj = None else: obj = self.get_object(request, unquote(object_id)) if self.has_view_permission(request, obj) and \ not self.has_change_permission(request, obj, True): extra_context = extra_context or {} extra_context['title'] = _('View %s') % force_text( opts.verbose_name) extra_context['show_save'] = False extra_context['show_save_and_continue'] = False inlines = self.get_inline_instances(request, obj) for inline in inlines: if inline.has_change_permission(request, obj, True): extra_context['show_save'] = True extra_context['show_save_and_continue'] = True break return super(AdminViewPermissionModelAdmin, self).change_view(request, object_id, form_url, extra_context)
def delete_view(self, request, object_id, extra_context=None): obj = self.get_object(request, unquote(object_id)) response = super(ProblemAdmin, self).delete_view(request, object_id, extra_context) if isinstance(response, HttpResponseRedirect): return self.redirect_to_list(request, obj) return response
def move_view(cls, request, admin_id, object_id, direction): qs = cls._get_changelist(request).get_queryset(request) obj = get_object_or_404(cls.model, pk=unquote(object_id)) obj.move(direction, qs) return HttpResponseRedirect('../../../%s' % cls.request_query_string)
def revision_view(self, request, object_id, version_id, extra_context=None): """Displays the contents of the given revision.""" object_id = unquote(object_id) # Underscores in primary key get quoted to "_5F" version = get_object_or_404(Version, pk=version_id, object_id=object_id) return self.revisionform_view(request, version, self.revision_form_template or self._get_template_list("revision_form.html"), { "title": _("Revert %(name)s") % {"name": version.object_repr}, })
def history_view(self, request, object_id, extra_context=None): """Renders the history view.""" # Check if user has change permissions for model if not self.has_change_permission(request): raise PermissionDenied object_id = unquote(object_id) # Underscores in primary key get quoted to "_5F" opts = self.model._meta action_list = [ { "revision": version.revision, "url": reverse( "%s:%s_%s_revision" % (self.admin_site.name, opts.app_label, opts.model_name), args=(quote(version.object_id), version.id) ), } for version in self._reversion_order_version_queryset(Version.objects.get_for_object_reference( self.model, object_id, ).select_related("revision__user")) ] # Compile the context. context = {"action_list": action_list} context.update(extra_context or {}) return super(VersionAdmin, self).history_view(request, object_id, context)
def history_view(self, request, object_id, extra_context=None): "The 'history' admin view for this model." model = self.model opts = model._meta app_label = opts.app_label pk_name = opts.pk.attname history = getattr(model, model._meta.simple_history_manager_attribute) object_id = unquote(object_id) action_list = history.filter(**{pk_name: object_id}) # If no history was found, see whether this object even exists. try: obj = model.objects.get(**{pk_name: object_id}) except model.DoesNotExist: try: obj = action_list.latest('history_date').instance except action_list.model.DoesNotExist: raise Http404 content_type = ContentType.objects.get_by_natural_key( *USER_NATURAL_KEY) admin_user_view = 'admin:%s_%s_change' % (content_type.app_label, content_type.model) context = { 'title': _('Change history: %s') % force_text(obj), 'action_list': action_list, 'module_name': capfirst(force_text(opts.verbose_name_plural)), 'object': obj, 'root_path': getattr(self.admin_site, 'root_path', None), 'app_label': app_label, 'opts': opts, 'admin_user_view': admin_user_view } context.update(extra_context or {}) return render(request, template_name=self.object_history_template, dictionary=context, current_app=self.admin_site.name)
def __init__(self, model_admin, instance_pk): super(MainMenuEditView, self).__init__(model_admin) self.instance_pk = unquote(instance_pk) self.pk_safe = quote(self.instance_pk) self.site = get_object_or_404(Site, id=self.instance_pk) self.instance = self.model.get_for_site(self.site) self.instance.save()
def move_view(self, request, object_id, direction): qs = self._get_changelist(request).get_queryset(request) obj = get_object_or_404(self.model, pk=unquote(object_id)) obj.move(direction, qs) return HttpResponseRedirect("../../{0!s}".format(self.request_query_string))
def run_view(self, request, query_hash, extra_context=None): obj = self.get_object(request, unquote(query_hash)) data = obj.query_data query_key = "qbe_query_%s" % query_hash if not query_key in request.session: request.session[query_key] = data return redirect("qbe_results", query_hash)
def __call__(self, request, url): ''' DEPRECATED!! More recent versions of Django use the get_urls method instead. Overriden to route extra URLs. ''' if url: if url.endswith('items/add'): return self.add_menu_item(request, unquote(url[:-10])) if url.endswith('items'): return HttpResponseRedirect('../') match = re.match('^(?P<menu_pk>[-\w]+)/items/(?P<menu_item_pk>[-\w]+)$', url) if match: return self.edit_menu_item(request, match.group('menu_pk'), match.group('menu_item_pk')) match = re.match('^(?P<menu_pk>[-\w]+)/items/(?P<menu_item_pk>[-\w]+)/delete$', url) if match: return self.delete_menu_item(request, match.group('menu_pk'), match.group('menu_item_pk')) match = re.match('^(?P<menu_pk>[-\w]+)/items/(?P<menu_item_pk>[-\w]+)/history$', url) if match: return self.history_menu_item(request, match.group('menu_pk'), match.group('menu_item_pk')) match = re.match('^(?P<menu_pk>[-\w]+)/items/(?P<menu_item_pk>[-\w]+)/move_up$', url) if match: return self.move_up_item(request, match.group('menu_pk'), match.group('menu_item_pk')) match = re.match('^(?P<menu_pk>[-\w]+)/items/(?P<menu_item_pk>[-\w]+)/move_down$', url) if match: return self.move_down_item(request, match.group('menu_pk'), match.group('menu_item_pk')) return super(MenuAdmin, self).__call__(request, url)
def user_change_password(self, request, id, form_url=''): if not self.has_change_permission(request): raise PermissionDenied user = self.get_object(request, unquote(id)) if user is None: raise Http404(_('%(name)s object with primary key %(key)r does not exist.') % { 'name': force_text(self.model._meta.verbose_name), 'key': escape(id), }) if request.method == 'POST': form = self.change_password_form(user, request.POST) if form.is_valid(): form.save() change_message = self.construct_change_message(request, form, None) self.log_change(request, user, change_message) msg = ugettext('Password changed successfully.') messages.success(request, msg) update_session_auth_hash(request, form.user) return HttpResponseRedirect( reverse( '%s:%s_%s_change' % ( self.admin_site.name, user._meta.app_label, user._meta.model_name, ), args=(user.pk,), ) ) else: form = self.change_password_form(user) fieldsets = [(None, {'fields': list(form.base_fields)})] adminForm = admin.helpers.AdminForm(form, fieldsets, {}) context = { 'title': _('Change password: %s') % escape(user.get_email()), 'adminForm': adminForm, 'form_url': form_url, 'form': form, 'is_popup': (IS_POPUP_VAR in request.POST or IS_POPUP_VAR in request.GET), 'add': True, 'change': False, 'has_delete_permission': False, 'has_change_permission': True, 'has_absolute_url': False, 'opts': self.model._meta, 'original': user, 'save_as': False, 'show_save': True, } context.update(self.admin_site.each_context(request)) request.current_app = self.admin_site.name return TemplateResponse(request, self.change_user_password_template or 'admin/auth/user/change_password.html', context)
def test_switch_moderator_off(self): with force_language("en"): pages_root = unquote(reverse("pages-root")) page1 = create_page('page', 'nav_playground.html', 'en', published=True) path = page1.get_absolute_url()[len(pages_root):].strip('/') page2 = get_page_from_path(path) self.assertIsNotNone(page2) self.assertEqual(page1.get_absolute_url(), page2.get_absolute_url())
def change_view (self, request, object_id, form_url='', extra_context=None): publish_now = request.GET.get('publish_now', '') if publish_now == '1': page = self.get_object(request, unquote(object_id)) version = page.version_set.get(publish__isnull=True) version.publish = timezone.now() version.save() self.message_user(request, '%s Published Successfully' % page.url, messages.SUCCESS) return http.HttpResponseRedirect('../') ret = super(PageAdmin, self).change_view(request, object_id, form_url=form_url, extra_context=extra_context) if request.method == 'GET' and isinstance(ret, TemplateResponse): if not ret.is_rendered: obj = self.get_object(request, unquote(object_id)) ret.context_data['inline_admin_formsets'] = self.regenerate_inlines(request, obj) return ret
def unlock_student(self, request, object_id=None, obj=None): """ Unlock student account. """ if object_id: obj = self.get_object(request, unquote(object_id)) self.model.clear_lockout_counter(obj.user)
def change_view(self, request, object_id, **kwargs): if kwargs.get('extra_context', None) is None: kwargs['extra_context'] = {} obj = self.get_object(request, unquote(object_id)) kwargs['extra_context']['object_tools_items'] = [ action.__dict__ for action in self.get_change_view_actions(obj) ] return super(ChangeViewActionsMixin, self).change_view(request, object_id, **kwargs)
def change_view(self, request, object_id, form_url='', extra_context=None): "The 'change' admin view for this model." model = self.model opts = model._meta obj = self.get_object(request, unquote(object_id)) if not self.has_change_permission(request, obj): raise PermissionDenied if obj is None: raise Http404(_('%(name)s object with primary key %(key)r does not exist.') \ % {'name': force_unicode(opts.verbose_name), 'key': escape(object_id)}) if request.method == 'POST' and '_saveasnew' in request.POST: return self.add_view(request, form_url='../add/') formsets = [] form = self.get_main_view_form(request, obj) if request.method == 'POST': if form.is_valid(): form_validated = True instance = self.save_form(request, form, change=True) else: form_validated = False instance = obj else: instance = obj for formset in self.get_formset_instances(request, instance, is_new=False): formsets.append(formset) if request.method == 'POST' and all_valid_with_nesting( formsets) and form_validated: self.save_view_formsets(request, instance, form, formsets, is_new=False) return self.response_change(request, instance) if hasattr(self, 'get_prepopulated_fields'): # Django 1.4 prepopulated_fields = self.get_prepopulated_fields(request, obj=obj) else: prepopulated_fields = self.prepopulated_fields adminForm = helpers.AdminForm(form, self.get_fieldsets(request, obj), prepopulated_fields, self.get_readonly_fields(request, obj), model_admin=self) media = self.media + adminForm.media inline_admin_formsets = [] for inline_admin_formset in self.get_inline_admin_formsets( request, formsets, obj): inline_admin_formsets.append(inline_admin_formset) media = media + inline_admin_formset.media for nested in getattr(inline_admin_formset, 'inlines', []): media += nested.media context = { 'title': _('Change %s') % force_unicode(opts.verbose_name), 'adminform': adminForm, 'object_id': object_id, 'original': obj, 'is_popup': (IS_POPUP_VAR in request.POST or IS_POPUP_VAR in request.GET), 'media': mark_safe(media), 'inline_admin_formsets': inline_admin_formsets, 'errors': helpers.AdminErrorList(form, formsets), 'root_path': reverse('admin:index'), 'app_label': opts.app_label, } if hasattr(self, 'get_preserved_filters'): # Django 1.6 context['preserved_filters'] = self.get_preserved_filters(request) context.update(extra_context or {}) return self.render_change_form(request, context, change=True, obj=obj, form_url=form_url)
def user_change_password(self, request, id, from_url=""): user = self.get_object(request, unquote(id)) operator = request.user if user.is_superuser and user.id != operator.id: raise PermissionDenied return UserAdmin.user_change_password(self, request, id)
def _delete_view(self, request, object_id, extra_context): """ The 'delete' admin view for this model. """ opts = self.model._meta app_label = opts.app_label to_field = request.POST.get(TO_FIELD_VAR, request.GET.get(TO_FIELD_VAR)) if to_field and not self.to_field_allowed(request, to_field): raise DisallowedModelAdminToField( "The field %s cannot be referenced." % to_field) obj = self.get_object(request, unquote(object_id), to_field) if not self.has_delete_permission(request, obj): raise PermissionDenied if obj is None: return self._get_obj_does_not_exist_redirect( request, opts, object_id) # Populate deleted_objects, a data structure of all related objects that # will also be deleted. ( deleted_objects, model_count, perms_needed, protected, ) = self.get_deleted_objects([obj], request) # frePPLe specific: Update the links to the related objects. if request.prefix: def replace_url(a): if isinstance(a, list): return [replace_url(i) for i in a] else: return mark_safe( a.replace('href="', 'href="%s' % request.prefix)) deleted_objects = [replace_url(i) for i in deleted_objects] protected = [replace_url(i) for i in protected] if request.POST and not protected: # The user has confirmed the deletion. if perms_needed: raise PermissionDenied obj_display = str(obj) attr = str(to_field) if to_field else opts.pk.attname obj_id = obj.serializable_value(attr) self.log_deletion(request, obj, obj_display) self.delete_model(request, obj) return self.response_delete(request, obj_display, obj_id) object_name = str(opts.verbose_name) if perms_needed or protected: title = _("Cannot delete %(name)s") % {"name": object_name} else: title = _("Are you sure?") context = { **self.admin_site.each_context(request), "title": title, "object_name": object_name, "object": obj, "object_id": obj, "deleted_objects": deleted_objects, "model_count": dict(model_count).items(), "perms_lacking": perms_needed, "protected": protected, "opts": opts, "app_label": app_label, "preserved_filters": self.get_preserved_filters(request), "is_popup": (IS_POPUP_VAR in request.POST or IS_POPUP_VAR in request.GET), "to_field": to_field, **(extra_context or {}), } return self.render_delete_form(request, context)
def __init__(self, model_admin, form_pk): self.form_pk = unquote(form_pk) object_qs = model_admin.model._default_manager.get_queryset() object_qs = object_qs.filter(pk=self.form_pk) self.form_instance = get_object_or_404(object_qs) super().__init__(model_admin)
def duplicate_view(self, request, object_id): """Duplicate a specified PageContent. Create a new page with content copied from provided PageContent. :param request: Http request :param object_id: PageContent ID (as a string) """ obj = self.get_object(request, unquote(object_id)) if obj is None: return self._get_obj_does_not_exist_redirect( request, self.model._meta, object_id) form = DuplicateForm( user=request.user, page_content=obj, initial={ "site": obj.page.node.site, "slug": obj.page.get_slug(obj.language), }, ) info = (self.model._meta.app_label, self.model._meta.model_name) if request.method == "POST": form = DuplicateForm(request.POST, user=request.user, page_content=obj) if form.is_valid(): new_page = obj.page.copy( site=form.cleaned_data["site"], parent_node=obj.page.node.parent, translations=False, permissions=False, extensions=False, ) new_page_content = api.create_title( page=new_page, language=obj.language, slug=form.cleaned_data["slug"], path=form.cleaned_data["path"], title=obj.title, template=obj.template, created_by=request.user, ) new_page.title_cache[obj.language] = new_page_content extension_pool.copy_extensions(source_page=obj.page, target_page=new_page, languages=[obj.language]) placeholders = obj.get_placeholders() for source_placeholder in placeholders: # Keep all placeholders even if they are not in the template anymore to ensure the data is kept, # keeping only placeholders from rescanning the template would not keep any legacy content # which could in theory be remapped repaired at a later date target_placeholder, created = new_page_content.placeholders.get_or_create( slot=source_placeholder.slot) source_placeholder.copy_plugins(target_placeholder, language=obj.language) self.message_user(request, _("Page has been duplicated")) return redirect(reverse( "admin:{}_{}_changelist".format(*info))) context = dict( obj=obj, form=form, object_id=object_id, duplicate_url=reverse("admin:{}_{}_duplicate".format(*info), args=(obj.pk, )), back_url=reverse("admin:{}_{}_changelist".format(*info)), ) return render(request, "djangocms_pageadmin/admin/duplicate_confirmation.html", context)
def change_view(self, request, object_id, form_url='', extra_context=None): "The 'change' admin view for this model." model = self.model opts = model._meta obj = self.get_object(request, unquote(object_id)) if not self.has_change_permission(request, obj): raise PermissionDenied if obj is None: raise Http404(_('%(name)s object with primary key %(key)r does not exist.') % {'name': force_text(opts.verbose_name), 'key': escape(object_id)}) if request.method == 'POST' and "_saveasnew" in request.POST: return self.add_view(request, form_url=reverse('admin:%s_%s_add' % (opts.app_label, opts.module_name), current_app=self.admin_site.name)) ModelForm = self.get_form(request, obj) formsets = [] inline_instances = self.get_inline_instances(request, obj) if request.method == 'POST': form = ModelForm(request.POST, request.FILES, instance=obj) if form.is_valid(): form_validated = True new_object = self.save_form(request, form, change=True) else: form_validated = False new_object = obj prefixes = {} for FormSet, inline in self.get_formsets_with_inlines(request, new_object): 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]) formset = FormSet(request.POST, request.FILES, instance=new_object, prefix=prefix, queryset=inline.get_queryset(request)) formsets.append(formset) if hasattr(inline, 'inlines') and inline.inlines: self.add_nested_inline_formsets(request, inline, formset) if self.all_valid_with_nesting(formsets) and form_validated: self.save_model(request, new_object, form, True) self.save_related(request, form, formsets, True) change_message = self.construct_change_message(request, form, formsets) self.log_change(request, new_object, change_message) return self.response_change(request, new_object) else: form = ModelForm(instance=obj) prefixes = {} for FormSet, inline in self.get_formsets_with_inlines(request, obj): 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]) formset = FormSet(instance=obj, prefix=prefix, queryset=inline.get_queryset(request)) formsets.append(formset) if hasattr(inline, 'inlines') and inline.inlines: self.add_nested_inline_formsets(request, inline, formset) adminForm = helpers.AdminForm(form, self.get_fieldsets(request, obj), self.get_prepopulated_fields(request, obj), self.get_readonly_fields(request, obj), model_admin=self) media = self.media + adminForm.media inline_admin_formsets = [] for inline, formset in zip(inline_instances, formsets): fieldsets = list(inline.get_fieldsets(request, obj)) readonly = list(inline.get_readonly_fields(request, obj)) prepopulated = dict(inline.get_prepopulated_fields(request, obj)) inline_admin_formset = helpers.InlineAdminFormSet(inline, formset, fieldsets, prepopulated, readonly, model_admin=self) inline_admin_formsets.append(inline_admin_formset) media = media + inline_admin_formset.media if hasattr(inline, 'inlines') and inline.inlines: media += self.wrap_nested_inline_formsets(request, inline, formset) context = { 'title': _('Change %s') % force_text(opts.verbose_name), 'adminform': adminForm, 'object_id': object_id, 'original': obj, 'is_popup': "_popup" in request.GET, 'media': media, 'inline_admin_formsets': inline_admin_formsets, 'errors': helpers.AdminErrorList(form, formsets), 'app_label': opts.app_label, } context.update(self.admin_site.each_context(request)) context.update(extra_context or {}) return self.render_change_form(request, context, change=True, obj=obj, form_url=form_url)
def obj_perms_manage_view(self, request, object_pk): """ Main object permissions view. Presents all users and groups with any object permissions for the current model *instance*. Users or groups without object permissions for related *instance* would **not** be shown. In order to add or manage user or group one should use links or forms presented within the page. """ # Note: had to override gurdian implementation as it was allowing # whoever has read/write permissions to instance to change the # permissions. if not self.has_change_permission(request, None): post_url = reverse('admin:index', current_app=self.admin_site.name) return redirect(post_url) try: # django >= 1.7 from django.contrib.admin.utils import unquote except ImportError: # django < 1.7 from django.contrib.admin.util import unquote obj = get_object_or_404(self.get_queryset(request), pk=unquote(object_pk)) owning_user = getattr(obj, self.user_owned_objects_field) if owning_user != request.user: post_url = reverse('admin:index', current_app=self.admin_site.name) return redirect(post_url) users_perms = OrderedDict( sorted(get_users_with_perms(obj, attach_perms=True, with_group_users=False).items(), key=lambda user: getattr(user[0], get_user_model().USERNAME_FIELD))) groups_perms = OrderedDict( sorted(get_groups_with_perms(obj, attach_perms=True).items(), key=lambda group: group[0].name)) if request.method == 'POST' and 'submit_manage_user' in request.POST: user_form = self.get_obj_perms_user_select_form(request)( request.POST) group_form = self.get_obj_perms_group_select_form(request)( request.POST) info = (self.admin_site.name, self.model._meta.app_label, get_model_name(self.model)) if user_form.is_valid(): user_id = user_form.cleaned_data['user'].pk url = reverse('%s:%s_%s_permissions_manage_user' % info, args=[obj.pk, user_id]) return redirect(url) elif request.method == 'POST' and 'submit_manage_group' in request.POST: user_form = self.get_obj_perms_user_select_form(request)( request.POST) group_form = self.get_obj_perms_group_select_form(request)( request.POST) info = (self.admin_site.name, self.model._meta.app_label, get_model_name(self.model)) if group_form.is_valid(): group_id = group_form.cleaned_data['group'].id url = reverse('%s:%s_%s_permissions_manage_group' % info, args=[obj.pk, group_id]) return redirect(url) else: user_form = self.get_obj_perms_user_select_form(request)() group_form = self.get_obj_perms_group_select_form(request)() context = self.get_obj_perms_base_context(request, obj) context['users_perms'] = users_perms context['groups_perms'] = groups_perms context['user_form'] = user_form context['group_form'] = group_form # https://github.com/django/django/commit/cf1f36bb6eb34fafe6c224003ad585a647f6117b request.current_app = self.admin_site.name if django.VERSION >= (1, 10): return render(request, self.get_obj_perms_manage_template(), context) return render_to_response(self.get_obj_perms_manage_template(), context, RequestContext(request))
def _changeform_view(self, request, object_id, form_url, extra_context): add = object_id is None model = self.model opts = model._meta if not self.has_add_permission(request): raise PermissionDenied model_form = self.get_form(request) formsets = [] if add: if not self.has_add_permission(request): raise PermissionDenied obj = None else: obj = self.get_object(request, unquote(object_id)) if not self.has_view_permission( request, obj) and not self.has_change_permission( request, obj): raise PermissionDenied if obj is None: return self._get_obj_does_not_exist_redirect( request, opts, object_id) if request.method == 'POST': form = model_form(request.POST, request.FILES, instance=obj) form_validated = form.is_valid() if form_validated: new_object = self.save_form(request, form, change=not add) else: new_object = form.instance 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: prefix = "%s-%s" % (prefix, prefixes[prefix]) formset = FormSet(data=request.POST, files=request.FILES, instance=new_object, save_as_new="_saveasnew" in request.POST, prefix=prefix) formsets.append(formset) if form_validated and _formsets_are_blank(request, new_object, formsets): self.save_model(request, new_object, form, change=not add) return self.response_add(request, new_object) elif form_validated and all_valid(formsets): # Here is the modified code. for formset, inline in zip(formsets, self.get_inline_instances(request)): if not isinstance(inline, ReverseInlineModelAdmin): continue obj_list = formset.save() if not hasattr(new_object, inline.parent_fk_name): obj = obj_list[0] if obj_list else None setattr(new_object, inline.parent_fk_name, obj) self.save_model(request, new_object, form, change=not add) form.save_m2m() for formset in formsets: self.save_formset(request, form, formset, change=not add) # self.log_addition(request, new_object) return self.response_add(request, new_object) else: # Prepare the dict of initial data from the request. # We have to special-case M2Ms as a list of comma-separated PKs. initial = dict(request.GET.items()) for k in initial: try: f = opts.get_field(k) except models.FieldDoesNotExist: continue if isinstance(f, models.ManyToManyField): initial[k] = initial[k].split(",") if add: form = model_form(initial=initial) 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: prefix = "%s-%s" % (prefix, prefixes[prefix]) formset = FormSet(instance=self.model(), prefix=prefix) formsets.append(formset) else: form = model_form(instance=obj) formsets, inline_instances = self._create_formsets(request, obj, change=True) adminForm = helpers.AdminForm(form, list(self.get_fieldsets(request)), self.prepopulated_fields) media = self.media + adminForm.media inline_admin_formsets = [] for inline, formset in zip(self.get_inline_instances(request), formsets): fieldsets = list(inline.get_fieldsets(request)) inline_admin_formset = helpers.InlineAdminFormSet( inline, formset, fieldsets) inline_admin_formsets.append(inline_admin_formset) media = media + inline_admin_formset.media context = { 'title': _('Add %s') % force_text(opts.verbose_name), 'adminform': adminForm, # 'is_popup': '_popup' in request.REQUEST, 'is_popup': False, 'show_delete': False, 'media': mark_safe(media), 'inline_admin_formsets': inline_admin_formsets, 'errors': helpers.AdminErrorList(form, formsets), # 'root_path': self.admin_site.root_path, 'app_label': opts.app_label, } context.update(extra_context or {}) return self.render_change_form(request, context, form_url=form_url, add=True)
def edit(request, app_label, model_name, pk): model = get_snippet_model_from_url_params(app_label, model_name) permission = get_permission_name('change', model) if not request.user.has_perm(permission): raise PermissionDenied instance = get_object_or_404(model, pk=unquote(pk)) for fn in hooks.get_hooks('before_edit_snippet'): result = fn(request, instance) if hasattr(result, 'status_code'): return result edit_handler = get_snippet_edit_handler(model) edit_handler = edit_handler.bind_to(instance=instance, request=request) form_class = edit_handler.get_form_class() if request.method == 'POST': form = form_class(request.POST, request.FILES, instance=instance) if form.is_valid(): with transaction.atomic(): form.save() log(instance=instance, action='wagtail.edit') messages.success( request, _("%(snippet_type)s '%(instance)s' updated.") % { 'snippet_type': capfirst(model._meta.verbose_name), 'instance': instance }, buttons=[ messages.button( reverse('wagtailsnippets:edit', args=(app_label, model_name, quote(instance.pk))), _('Edit')) ]) for fn in hooks.get_hooks('after_edit_snippet'): result = fn(request, instance) if hasattr(result, 'status_code'): return result return redirect('wagtailsnippets:list', app_label, model_name) else: messages.validation_error( request, _("The snippet could not be saved due to errors."), form) else: form = form_class(instance=instance) edit_handler = edit_handler.bind_to(form=form) latest_log_entry = log_registry.get_logs_for_instance(instance).first() context = { 'model_opts': model._meta, 'instance': instance, 'edit_handler': edit_handler, 'form': form, 'action_menu': SnippetActionMenu(request, view='edit', instance=instance), 'locale': None, 'translations': [], 'latest_log_entry': latest_log_entry, } if getattr(settings, 'WAGTAIL_I18N_ENABLED', False) and issubclass( model, TranslatableMixin): context.update({ 'locale': instance.locale, 'translations': [{ 'locale': translation.locale, 'url': reverse('wagtailsnippets:edit', args=[app_label, model_name, quote(translation.pk)]) } for translation in instance.get_translations().select_related( 'locale')], }) return TemplateResponse(request, 'wagtailsnippets/snippets/edit.html', context)
def delete(request, app_label, model_name, pk=None): model = get_snippet_model_from_url_params(app_label, model_name) permission = get_permission_name('delete', model) if not request.user.has_perm(permission): raise PermissionDenied if pk: instances = [get_object_or_404(model, pk=unquote(pk))] else: ids = request.GET.getlist('id') instances = model.objects.filter(pk__in=ids) for fn in hooks.get_hooks('before_delete_snippet'): result = fn(request, instances) if hasattr(result, 'status_code'): return result count = len(instances) if request.method == 'POST': with transaction.atomic(): for instance in instances: log(instance=instance, action='wagtail.delete') instance.delete() if count == 1: message_content = _("%(snippet_type)s '%(instance)s' deleted.") % { 'snippet_type': capfirst(model._meta.verbose_name), 'instance': instance } else: # This message is only used in plural form, but we'll define it with ngettext so that # languages with multiple plural forms can be handled correctly (or, at least, as # correctly as possible within the limitations of verbose_name_plural...) message_content = ngettext( "%(count)d %(snippet_type)s deleted.", "%(count)d %(snippet_type)s deleted.", count) % { 'snippet_type': capfirst(model._meta.verbose_name_plural), 'count': count } messages.success(request, message_content) for fn in hooks.get_hooks('after_delete_snippet'): result = fn(request, instances) if hasattr(result, 'status_code'): return result return redirect('wagtailsnippets:list', app_label, model_name) return TemplateResponse( request, 'wagtailsnippets/snippets/confirm_delete.html', { 'model_opts': model._meta, 'count': count, 'instances': instances, 'submit_url': (reverse('wagtailsnippets:delete-multiple', args=(app_label, model_name)) + '?' + urlencode([('id', instance.pk) for instance in instances])), })
def compare_view(self, request, object_id): """Compares two versions """ # Get version 1 (the version we're comparing against) v1 = self.get_object(request, unquote(object_id)) if v1 is None: return self._get_obj_does_not_exist_redirect( request, self.model._meta, object_id) persist_params = { get_cms_setting("CMS_TOOLBAR_URL__DISABLE"): 1, get_cms_setting("CMS_TOOLBAR_URL__PERSIST"): 0, } v1_preview_url = add_url_parameters( reverse( "admin:cms_placeholder_render_object_preview", args=(v1.content_type_id, v1.object_id), ), **persist_params) # Get the list of versions for the grouper. This is for use # in the dropdown to choose a version. version_list = Version.objects.filter_by_content_grouping_values( v1.content).order_by("-number") # Add the above to context context = { "version_list": version_list, "v1": v1, "v1_preview_url": v1_preview_url, "v1_description": format_html( 'Version #{number} ({date})', obj=v1, number=v1.number, date=localize(localtime(v1.created)), ), "return_url": version_list_url(v1.content), } # Now check if version 2 has been specified and add to context # if yes if "compare_to" in request.GET: v2 = self.get_object(request, unquote(request.GET["compare_to"])) if v2 is None: return self._get_obj_does_not_exist_redirect( request, self.model._meta, request.GET["compare_to"]) else: context.update({ "v2": v2, "v2_preview_url": add_url_parameters( reverse( "admin:cms_placeholder_render_object_preview", args=(v2.content_type_id, v2.object_id), ), **persist_params), "v2_description": format_html( 'Version #{number} ({date})', obj=v2, number=v2.number, date=localize(localtime(v2.created)), ), }) return TemplateResponse(request, "djangocms_versioning/admin/compare.html", context)
def user_change_password(self, request, id, form_url=""): if not self.has_change_permission(request): raise PermissionDenied user = self.get_object(request, unquote(id)) if user is None: raise Http404( _("%(name)s object with primary key %(key)r does not exist.") % { "name": self.model._meta.verbose_name, "key": escape(id), }) if request.method == "POST": form = self.change_password_form(user, request.POST) if form.is_valid(): form.save() change_message = self.construct_change_message( request, form, None) self.log_change(request, user, change_message) msg = gettext("Password changed successfully.") messages.success(request, msg) update_session_auth_hash(request, form.user) return HttpResponseRedirect( reverse( "%s:%s_%s_change" % ( self.admin_site.name, user._meta.app_label, user._meta.model_name, ), args=(user.pk, ), )) else: form = self.change_password_form(user) fieldsets = [(None, {"fields": list(form.base_fields)})] adminForm = admin.helpers.AdminForm(form, fieldsets, {}) context = { "title": _("Change password: %s") % escape(user.get_username()), "adminForm": adminForm, "form_url": form_url, "form": form, "is_popup": (IS_POPUP_VAR in request.POST or IS_POPUP_VAR in request.GET), "add": True, "change": False, "has_delete_permission": False, "has_change_permission": True, "has_absolute_url": False, "opts": self.model._meta, "original": user, "save_as": False, "show_save": True, } context.update(self.admin_site.each_context(request)) request.current_app = self.admin_site.name return TemplateResponse( request, self.change_user_password_template or "admin/auth/user/change_password.html", context, )
def move_view(self, request, object_id): with transaction.atomic(using=router.db_for_write(self.model)): model = self.model opts = model._meta obj = self.get_object(request, unquote(object_id)) if not self.has_change_permission(request, obj): raise PermissionDenied if obj is None: raise Http404() if request.method == 'POST': form = MoveForm(request.POST, obj=obj) if form.is_valid(): form.save() self.message_user( request, _('The node %(node)s has been made the' ' %(move_to)s of node %(to)s.') % { 'node': obj, 'move_to': dict(MoveForm.MOVE_CHOICES).get( form.cleaned_data['move_to'], form.cleaned_data['move_to']), 'to': form.cleaned_data['of'] or _('root node'), }) return redirect('admin:%s_%s_changelist' % (opts.app_label, opts.model_name)) else: form = MoveForm(obj=obj) adminForm = helpers.AdminForm( form, [(None, { 'fields': ('move_to', 'of'), })], # list(self.get_fieldsets(request, obj)), {}, # self.get_prepopulated_fields(request, obj), (), # self.get_readonly_fields(request, obj), model_admin=self) media = self.media + adminForm.media context = dict( self.admin_site.each_context(request), title=_('Move %s') % obj, object_id=object_id, original=obj, adminform=adminForm, errors=helpers.AdminErrorList(form, ()), preserved_filters=self.get_preserved_filters(request), media=media, is_popup=False, save_as_new=False, show_save_and_add_another=False, show_save_and_continue=False, show_delete=False, ) return self.render_change_form(request, context, add=False, change=False, obj=obj)
def changeform_view(self, request, object_id=None, form_url='', extra_context=None): to_field = request.POST.get(TO_FIELD_VAR, request.GET.get(TO_FIELD_VAR)) if to_field and not self.to_field_allowed(request, to_field): raise DisallowedModelAdminToField("The field %s cannot be referenced." % to_field) model = self.model opts = model._meta if request.method == 'POST' and '_saveasnew' in request.POST: object_id = None add = object_id is None if add: if not self.has_add_permission(request): raise PermissionDenied obj = None else: obj = self.get_object(request, unquote(object_id), to_field) if not self.has_change_permission(request, obj): raise PermissionDenied if obj is None: raise Http404(_('%(name)s object with primary key %(key)r does not exist.') % { 'name': force_text(opts.verbose_name), 'key': escape(object_id)}) ModelForm = self.get_form(request, obj) if request.method == 'POST': form = ModelForm(request.POST, request.FILES, instance=obj) if form.is_valid(): form_validated = True new_object = self.save_form(request, form, change=not add) else: form_validated = False new_object = form.instance formsets, inline_instances = self._create_formsets(request, new_object, change=not add) if all_valid(formsets) and form_validated: self.save_model(request, new_object, form, not add) self.save_related(request, form, formsets, not add) change_message = self.construct_change_message(request, form, formsets, add) if add: self.log_addition(request, new_object, change_message) return self.response_add(request, new_object) else: self.log_change(request, new_object, change_message) return self.response_change(request, new_object) else: form_validated = False else: if add: initial = self.get_changeform_initial_data(request) form = ModelForm(initial=initial) formsets, inline_instances = self._create_formsets(request, form.instance, change=False) else: form = ModelForm(instance=obj) formsets, inline_instances = self._create_formsets(request, obj, change=True) adminForm = helpers.AdminForm( form, list(self.get_fieldsets(request, obj)), self.get_prepopulated_fields(request, obj), self.get_readonly_fields(request, obj), model_admin=self) media = self.media + adminForm.media inline_formsets = self.get_inline_formsets(request, formsets, inline_instances, obj) for inline_formset in inline_formsets: media = media + inline_formset.media context = dict(self.admin_site.each_context(request), title=(_('Add %s') if add else _('Change %s')) % force_text(opts.verbose_name), adminform=adminForm, object_id=object_id, original=obj, is_popup=(IS_POPUP_VAR in request.POST or IS_POPUP_VAR in request.GET), to_field=to_field, media=media, inline_admin_formsets=inline_formsets, errors=helpers.AdminErrorList(form, formsets), preserved_filters=self.get_preserved_filters(request), ) # Hide the "Save" and "Save and continue" buttons if "Save as New" was # previously chosen to prevent the interface from getting confusing. if request.method == 'POST' and not form_validated and "_saveasnew" in request.POST: context['show_save'] = False context['show_save_and_continue'] = False # Use the change template instead of the add template. add = False context.update(extra_context or {}) return self.render_change_form(request, context, add=add, change=not add, obj=obj, form_url=form_url)
def user_change_password(self, request, id, form_url=''): user = self.get_object(request, unquote(id)) if not self.has_change_permission(request, user): raise PermissionDenied if user is None: raise Http404(_('%(name)s object with primary key %(key)r does not exist.') % { 'name': self.model._meta.verbose_name, 'key': escape(id), }) if request.method == 'POST': form = self.change_password_form(user, request.POST) if form.is_valid(): form.save() change_message = self.construct_change_message(request, form, None) self.log_change(request, user, change_message) msg = gettext('Password changed successfully.') messages.success(request, msg) update_session_auth_hash(request, form.user) return HttpResponseRedirect( reverse( '%s:%s_%s_change' % ( self.admin_site.name, user._meta.app_label, user._meta.model_name, ), args=(user.pk,), ) ) else: form = self.change_password_form(user) fieldsets = [(None, {'fields': list(form.base_fields)})] adminForm = admin.helpers.AdminForm(form, fieldsets, {}) context = { 'title': _('Change password: %s') % escape(user.get_username()), 'adminForm': adminForm, 'form_url': form_url, 'form': form, 'is_popup': (IS_POPUP_VAR in request.POST or IS_POPUP_VAR in request.GET), 'add': True, 'change': False, 'has_delete_permission': False, 'has_change_permission': True, 'has_absolute_url': False, 'opts': self.model._meta, 'original': user, 'save_as': False, 'show_save': True, **self.admin_site.each_context(request), } request.current_app = self.admin_site.name return TemplateResponse( request, self.change_user_password_template or 'admin/auth/user/change_password.html', context, )
def rename_view(self, request, object_id, extra_context=None): "The 'rename' admin view for this model." model = self.model opts = model._meta try: obj = self.get_queryset(request).get(pk=unquote(object_id)) except model.DoesNotExist: # Don't raise Http404 just yet, because we haven't checked # permissions yet. We don't want an unauthenticated user to be able # to determine whether a given object exists. obj = None if not self.has_change_permission(request, obj): raise PermissionDenied if obj is None: raise Http404( _('%(name)s object with primary key %(key)r does not exist.') % { 'name': force_unicode(opts.verbose_name), 'key': escape(object_id) }) RenameForm = self.get_rename_form(request, obj) if request.method == 'POST': with transaction.atomic(): form = RenameForm(request.POST) if form.is_valid(): form_validated = True new_object = self.save_rename(request, obj, form) else: form_validated = False new_object = obj if form_validated: rename_message = _('Renamed {old} to {new}').format( old=obj.pk, new=new_object.pk) self.log_change(request, new_object, rename_message) return self.response_rename(request, new_object) else: form = RenameForm() media = self.media + form.media context = { 'title': _('Rename %s') % force_unicode(opts.verbose_name), 'form': form, 'object_id': object_id, 'original': obj, 'is_popup': (IS_POPUP_VAR in request.POST or IS_POPUP_VAR in request.GET), 'errors': form.errors, 'media': mark_safe(media), 'app_label': opts.app_label, } context.update(extra_context or {}) return self.render_rename_form(request, context, obj=obj)
def delete_view(self, request, object_id, extra_context=None): self.personform = self.get_object(request, unquote(object_id)).form return super().delete_view(request, object_id, extra_context)
def delete_translation(self, request, object_id, language_code): "The 'delete translation' admin view for this model." opts = self.model._meta app_label = opts.app_label translations_model = opts.translations_model try: obj = translations_model.objects.select_related('master').get( master__pk=unquote(object_id), language_code=language_code) except translations_model.DoesNotExist: raise Http404 if not self.has_delete_permission(request, obj): raise PermissionDenied if len(self.get_available_languages(obj.master)) <= 1: return self.deletion_not_allowed(request, obj, language_code) using = router.db_for_write(translations_model) # Populate deleted_objects, a data structure of all related objects that # will also be deleted. protected = False deleted_objects, perms_needed, protected = get_deleted_objects( [obj], translations_model._meta, request.user, self.admin_site, using) lang = get_language_name(language_code) if request.POST: # The user has already confirmed the deletion. if perms_needed: raise PermissionDenied obj_display = '%s translation of %s' % (lang, force_text(obj.master)) self.log_deletion(request, obj, obj_display) self.delete_model_translation(request, obj) self.message_user(request, _('The %(name)s "%(obj)s" was deleted successfully.') % { 'name': force_text(opts.verbose_name), 'obj': force_text(obj_display) } ) if not self.has_change_permission(request, None): return HttpResponseRedirect(self.reverse('admin:index')) model_name = opts.model_name if django.VERSION >= (1, 6) else opts.module_name return HttpResponseRedirect(self.reverse('admin:%s_%s_changelist' % (opts.app_label, model_name))) object_name = '%s Translation' % force_text(opts.verbose_name) if perms_needed or protected: title = _("Cannot delete %(name)s") % {"name": object_name} else: title = _("Are you sure?") context = { "title": title, "object_name": object_name, "object": obj, "deleted_objects": deleted_objects, "perms_lacking": perms_needed, "protected": protected, "opts": opts, "app_label": app_label, } return render_to_response(self.delete_confirmation_template or [ "admin/%s/%s/delete_confirmation.html" % (app_label, opts.object_name.lower()), "admin/%s/delete_confirmation.html" % app_label, "admin/delete_confirmation.html" ], context, RequestContext(request))
def mass_change_view(self, request, comma_separated_object_ids, extra_context=None): """The 'mass change' admin view for this model.""" global new_object model = self.model opts = model._meta general_error = None # Allow model to hide some fields for mass admin exclude_fields = getattr(self.admin_obj, "massadmin_exclude", ()) queryset = getattr(self.admin_obj, "massadmin_queryset", self.get_queryset)(request) object_ids = comma_separated_object_ids.split(',') object_id = object_ids[0] try: obj = queryset.get(pk=unquote(object_id)) except model.DoesNotExist: obj = None # TODO It's necessary to check permission and existence for all object if not self.has_change_permission(request, obj): raise PermissionDenied if obj is None: raise Http404( _('%(name)s object with primary key %(key)r does not exist.') % { 'name': force_text(opts.verbose_name), 'key': escape(object_id) }) ModelForm = self.get_form(request, obj) formsets = [] errors, errors_list = None, None mass_changes_fields = request.POST.getlist("_mass_change") if request.method == 'POST': # commit only when all forms are valid try: with transaction.atomic(): objects_count = 0 changed_count = 0 objects = queryset.filter(pk__in=object_ids) for obj in objects: objects_count += 1 form = ModelForm(request.POST, request.FILES, instance=obj) exclude = [] for fieldname, field in list(form.fields.items()): if fieldname not in mass_changes_fields: exclude.append(fieldname) for exclude_fieldname in exclude: del form.fields[exclude_fieldname] if form.is_valid(): form_validated = True new_object = self.save_form(request, form, change=True) else: form_validated = False new_object = obj prefixes = {} for FormSet in get_formsets(self, request, new_object): prefix = FormSet.get_default_prefix() prefixes[prefix] = prefixes.get(prefix, 0) + 1 if prefixes[prefix] != 1: prefix = "%s-%s" % (prefix, prefixes[prefix]) if prefix in mass_changes_fields: formset = FormSet(request.POST, request.FILES, instance=new_object, prefix=prefix) formsets.append(formset) if all_valid(formsets) and form_validated: # self.admin_obj.save_model(request, new_object, form, change=True) self.save_model(request, new_object, form, change=True) form.save_m2m() for formset in formsets: self.save_formset(request, form, formset, change=True) change_message = self.construct_change_message( request, form, formsets) self.log_change(request, new_object, change_message) changed_count += 1 if changed_count == objects_count: return self.response_change(request, new_object) else: errors = form.errors errors_list = helpers.AdminErrorList(form, formsets) # Raise error for rollback transaction in atomic block raise ValidationError("Not all forms is correct") except: general_error = sys.exc_info()[1] form = ModelForm(instance=obj) form._errors = errors prefixes = {} for FormSet in get_formsets(self, request, obj): prefix = FormSet.get_default_prefix() prefixes[prefix] = prefixes.get(prefix, 0) + 1 if prefixes[prefix] != 1: prefix = "%s-%s" % (prefix, prefixes[prefix]) formset = FormSet(instance=obj, prefix=prefix) formsets.append(formset) adminForm = helpers.AdminForm(form, self.get_fieldsets(request, obj), self.prepopulated_fields, self.get_readonly_fields(request, obj), model_admin=self.admin_obj) media = self.media + adminForm.media # We don't want the user trying to mass change unique fields! unique_fields = [] try: # Django >= 1.9 fields = model._meta.get_fields() except: fields = model._meta.get_all_field_names() for field_name in fields: try: field = model._meta.get_field(field_name) if field.unique: unique_fields.append(field_name) except: pass # Buggy! Use at your own risk #inline_admin_formsets = [] # for inline, formset in zip(self.inline_instances, formsets): # fieldsets = list(inline.get_fieldsets(request, obj)) # inline_admin_formset = helpers.InlineAdminFormSet(inline, formset, fieldsets) # inline_admin_formsets.append(inline_admin_formset) # media = media + inline_admin_formset.media context = { 'title': _('Change %s') % force_text(opts.verbose_name), 'adminform': adminForm, 'object_id': object_id, 'original': obj, 'unique_fields': unique_fields, 'exclude_fields': exclude_fields, 'is_popup': '_popup' in request.GET or '_popup' in request.POST, 'media': mark_safe(media), #'inline_admin_formsets': inline_admin_formsets, 'errors': errors_list, 'general_error': general_error, 'app_label': opts.app_label, 'object_ids': comma_separated_object_ids, 'mass_changes_fields': mass_changes_fields, } context.update(extra_context or {}) return self.render_mass_change_form(request, context, change=True, obj=obj)
def compare_view(self, request, object_id, extra_context=None): """ compare two versions. Used self.make_compare() to create the html diff. """ if self.compare is None: raise Http404("Compare view not enabled.") form = SelectDiffForm(request.GET) if not form.is_valid(): msg = "Wrong version IDs." if settings.DEBUG: msg += " (form errors: %s)" % ", ".join(form.errors) raise Http404(msg) version_id1 = form.cleaned_data["version_id1"] version_id2 = form.cleaned_data["version_id2"] if version_id1 > version_id2: # Compare always the newest one (#2) with the older one (#1) version_id1, version_id2 = version_id2, version_id1 object_id = unquote( object_id) # Underscores in primary key get quoted to "_5F" obj = get_object_or_404(self.model, pk=object_id) queryset = reversion_api.get_for_object(obj) version1 = get_object_or_404(queryset, pk=version_id1) version2 = get_object_or_404(queryset, pk=version_id2) next_version = queryset.filter(pk__gt=version_id2).last() prev_version = queryset.filter(pk__lt=version_id1).first() compare_data, has_unfollowed_fields = self.compare( obj, version1, version2) opts = self.model._meta context = { "opts": opts, "app_label": opts.app_label, "model_name": capfirst(opts.verbose_name), "title": _("Compare %(name)s") % { "name": version1.object_repr }, "obj": obj, "compare_data": compare_data, "has_unfollowed_fields": has_unfollowed_fields, "version1": version1, "version2": version2, "changelist_url": reverse("%s:%s_%s_changelist" % (self.admin_site.name, opts.app_label, opts.model_name)), "change_url": reverse("%s:%s_%s_change" % (self.admin_site.name, opts.app_label, opts.model_name), args=(quote(obj.pk), )), "original": obj, "history_url": reverse("%s:%s_%s_history" % (self.admin_site.name, opts.app_label, opts.model_name), args=(quote(obj.pk), )), } # don't use urlencode with dict for generate prev/next-urls # Otherwise we can't unitests it! if next_version: next_url = "?version_id1=%i&version_id2=%i" % (version2.id, next_version.id) context.update({'next_url': next_url}) if prev_version: prev_url = "?version_id1=%i&version_id2=%i" % (prev_version.id, version1.id) context.update({'prev_url': prev_url}) extra_context = extra_context or {} context.update(extra_context) return render_to_response( self.compare_template or self._get_template_list("compare.html"), context, template.RequestContext(request))
def delete_translation(self, request, object_id, language_code): """ The 'delete translation' admin view for this model. """ opts = self.model._meta root_model = self.model._parler_meta.root_model # Get object and translation shared_obj = self.get_object(request, unquote(object_id)) if shared_obj is None: raise Http404 shared_obj.set_current_language(language_code) try: translation = root_model.objects.get(master=shared_obj, language_code=language_code) except root_model.DoesNotExist: raise Http404 if not self.has_delete_permission(request, translation): raise PermissionDenied if len(self.get_available_languages(shared_obj)) <= 1: return self.deletion_not_allowed(request, translation, language_code) # Populate deleted_objects, a data structure of all related objects that # will also be deleted. using = router.db_for_write(root_model) # NOTE: all same DB for now. lang = get_language_title(language_code) # There are potentially multiple objects to delete; # the translation object at the base level, # and additional objects that can be added by inherited models. deleted_objects = [] perms_needed = False protected = [] # Extend deleted objects with the inlines. for qs in self.get_translation_objects( request, translation.language_code, obj=shared_obj, inlines=self.delete_inline_translations): if isinstance(qs, (list, tuple)): qs_opts = qs[0]._meta else: qs_opts = qs.model._meta deleted_result = get_deleted_objects(qs, qs_opts, request.user, self.admin_site, using) if django.VERSION >= (1, 8): (del2, model_counts, perms2, protected2) = deleted_result else: (del2, perms2, protected2) = deleted_result deleted_objects += del2 perms_needed = perms_needed or perms2 protected += protected2 if request.POST: # The user has already confirmed the deletion. if perms_needed: raise PermissionDenied obj_display = _('{0} translation of {1}').format( lang, force_text(translation)) # in hvad: (translation.master) self.log_deletion(request, translation, obj_display) self.delete_model_translation(request, translation) self.message_user( request, _('The %(name)s "%(obj)s" was deleted successfully.') % dict(name=force_text(opts.verbose_name), obj=force_text(obj_display))) if self.has_change_permission(request, None): info = _get_model_meta(opts) return HttpResponseRedirect( reverse('admin:{0}_{1}_change'.format(*info), args=(object_id, ), current_app=self.admin_site.name)) else: return HttpResponseRedirect( reverse('admin:index', current_app=self.admin_site.name)) object_name = _('{0} Translation').format(force_text( opts.verbose_name)) if perms_needed or protected: title = _("Cannot delete %(name)s") % {"name": object_name} else: title = _("Are you sure?") context = { "title": title, "object_name": object_name, "object": translation, "deleted_objects": deleted_objects, "perms_lacking": perms_needed, "protected": protected, "opts": opts, "app_label": opts.app_label, } return render( request, self.delete_confirmation_template or [ "admin/%s/%s/delete_confirmation.html" % (opts.app_label, opts.object_name.lower()), "admin/%s/delete_confirmation.html" % opts.app_label, "admin/delete_confirmation.html" ], context)
def pdf_letter_view(self, request, object_id, extra_context=None): from evan.site.pdfs.registrations import InvitationLetterPdfMaker obj = self.get_object(request, unquote(object_id)) maker = InvitationLetterPdfMaker(registration=obj, filename=f"letter--{obj.uuid}.pdf", as_attachment=False) return maker.response
def change_view(self, request, object_id, form_url='', extra_context=None): extra_context = extra_context or {} execlude = [ 'babysitter', 'status', ] model = self.model opts = model._meta if not self.has_add_permission(request): raise PermissionDenied model_form = self.get_form(request) formsets = [] obj = self.get_object(request, unquote(object_id)) if not self.has_view_permission( request, obj) and not self.has_change_permission(request, obj): raise PermissionDenied if obj is None: return self._get_obj_does_not_exist_redirect( request, opts, object_id) inline_instances = [] inline_admin_formsets = [] if request.method == 'POST': form = model_form(request.POST, request.FILES, instance=obj) print("post form") print(form) form_validated = form.is_valid() if form_validated: new_object = self.save_form(request, form, change=True) #not add else: new_object = form.instance #print("-----------new_object--------------------") #print(new_object) prefixes = {} #print("self.get_formsets_with_inlines(request)-------------------------") #print(self.get_formsets_with_inlines(request)) #print("self.get_formsets_with_inlines(request)-------------------------") #print(self.get_formsets_with_inlines(request)) for FormSet, inline in self.get_formsets_with_inlines(request): #print("Formset inline") #print(FormSet) #print(inline) prefix = FormSet.get_default_prefix() prefixes[prefix] = prefixes.get(prefix, 0) + 1 if prefixes[prefix] != 1: prefix = "%s-%s" % (prefix, prefixes[prefix]) #print("prefix---------------------------") #print(prefix) #data1 = copy.deepcopy(request.POST) '''tmp_data = { 'form-TOTAL_FORMS': ['2'], 'form-INITIAL_FORMS': '2', 'form-MAX_NUM_FORMS': '2', 'form-MIN_NUM_FORMS': '2', }''' #data.update(tmp_data) '''data1['form-TOTAL_FORMS'] = '1' data1['form-INITIAL_FORMS'] = '1' data1['form-MAX_NUM_FORMS'] = '1' data1['form-MIN_NUM_FORMS'] = '0' print("data=data----------------")''' #print(data1) formset = FormSet(data=request.POST, files=request.FILES, instance=new_object, save_as_new="_saveasnew" in request.POST) #prefix=prefix) ##print("formset") #print(formset) formsets.append(formset) print("-------------form_validated----------") print(form_validated) print("-------_formsets_are_blank-------------------") print(_formsets_are_blank(request, new_object, formsets)) print("all_valid(formsets)") f = all_valid(formsets) print(f) if form_validated and _formsets_are_blank(request, new_object, formsets): print("-------_formsets_are_blank-------------------") self.save_model(request, new_object, form, change=True) #not add) return self.response_add(request, new_object) elif form_validated and all_valid(formsets): # Here is the modified code. print("-------------form_validated----------") for formset, inline in zip(formsets, self.get_inline_instances(request)): print("-------------form_validated for loop----------") print(inine) if not isinstance(inline, ReverseInlineModelAdmin): continue # The idea or this piece is coming from https://stackoverflow.com/questions/50910152/inline-formset-returns-empty-list-on-save. # Without this, formset.save() was returning None for forms that # haven't been modified forms = [f for f in formset] if not forms: continue obj = forms[0].save() print("----------form obj----------------") print(obj) setattr(new_object, inline.parent_fk_name, obj) self.save_model(request, new_object, form, change=not add) form.save_m2m() for formset in formsets: self.save_formset(request, form, formset, change=not add) # self.log_addition(request, new_object) return self.response_add(request, new_object) else: form = model_form(instance=obj) formsets, inline_instances = self._create_formsets(request, obj, change=True) print("else -----------------formsets") print(formsets) print("formsets") #inline_instances = [] #inline_admin_formsets = [] for field in self.model._meta.get_fields(): if isinstance(field, (OneToOneField, ForeignKey)): parent = field.remote_field.model BabysitterFormSet = modelformset_factory( Babysitter, fields=('peference_hours_per_day', 'preference_no_of_children', 'preference_locations'), extra=0) babysitter_form = BabysitterFormSet( queryset=Babysitter.objects.filter( user_id=obj.babysitter.user.id)) '''print("model--------------------") print(model) print("parent---------------------") print(parent)''' name = field.name inline_type = "stacked" babysitter_inline = ReverseInlineModelAdmin( model, name, parent, self.admin_site, inline_type) kwargs = { 'fields': [ 'peference_hours_per_day', 'preference_no_of_children', 'preference_locations' ] } babysitter_inline.__dict__.update(kwargs) inline_instances.append(babysitter_inline) fieldsets = [(None, { 'fields': [ 'peference_hours_per_day', 'preference_no_of_children', 'preference_locations' ] })] inline_admin_formset = helpers.InlineAdminFormSet( babysitter_inline, babysitter_form, fieldsets) inline_admin_formsets.append(inline_admin_formset) for field in parent._meta.get_fields(): if isinstance(field, (OneToOneField, ForeignKey)): parent = field.remote_field.model UserFormSet = modelformset_factory( UserProfile, fields=('username', 'first_name', 'last_name', 'email', 'is_active', 'primary_contact_number', 'alternate_contact_number', 'address', 'avatar'), extra=0) user_form = UserFormSet( queryset=UserProfile.objects.filter( id=obj.babysitter.user.id)) model = field.model '''print("model--------------------") print(model) print("parent---------------------") print(parent) print("field------------") print(field.model)''' name = field.name inline_type = "stacked" user_inline = ReverseInlineModelAdmin( model, name, parent, self.admin_site, inline_type) kwargs = { 'fields': [ 'username', 'first_name', 'last_name', 'email', 'is_active', 'primary_contact_number', 'alternate_contact_number', 'address', 'avatar' ] } user_inline.__dict__.update(kwargs) inline_instances.append(user_inline) fieldsets = [(None, { 'fields': [ 'username', 'first_name', 'last_name', 'email', 'is_active', 'primary_contact_number', 'alternate_contact_number', 'address', 'avatar' ] })] inline_admin_formset = helpers.InlineAdminFormSet( user_inline, user_form, fieldsets) inline_admin_formsets.append(inline_admin_formset) self.tmp_inline_instances = inline_instances readonly_fields = self.get_readonly_fields(request, obj) adminForm = helpers.AdminForm(form, list(self.get_fieldsets(request)), self.prepopulated_fields, readonly_fields=readonly_fields, model_admin=self) media = self.media + adminForm.media '''inline_admin_formsets = [] for inline, formset in zip(self.get_inline_instances(request), formsets): fieldsets = list(inline.get_fieldsets(request)) inline_admin_formset = helpers.InlineAdminFormSet(inline, formset, fieldsets) inline_admin_formsets.append(inline_admin_formset) #print('inline_admin_formset--------------') #print(inline_admin_formset) #print(inline) #print(fieldsets) #print(inline_admin_formset.has_add_permission) media = media + inline_admin_formset.media''' context = self.admin_site.each_context(request) reverse_admin_context = { #'title': _(('Change %s', 'Add %s')[add] % force_text(opts.verbose_name)), 'adminform': adminForm, # 'is_popup': '_popup' in request.REQUEST, 'is_popup': False, 'show_delete': False, 'media': mark_safe(media), 'inline_admin_formsets': inline_admin_formsets, 'errors': helpers.AdminErrorList(form, formsets), # 'root_path': self.admin_site.root_path, 'app_label': opts.app_label, } print("------------errors-----------") errors = helpers.AdminErrorList(form, formsets) print(errors) context.update(reverse_admin_context) context.update(extra_context or {}) return self.render_change_form(request, context, form_url=form_url, add=False)
def changeform_view(self, request, object_id=None, form_url='', extra_context=None): """ Overriding the changeform view of ModelAdmin to allow the form view to be displayed when the user only has view permissions. In this case, the form view will be displayed in readonly mode and without action buttons """ to_field = request.POST.get(TO_FIELD_VAR, request.GET.get(TO_FIELD_VAR)) if to_field and not self.to_field_allowed(request, to_field): raise DisallowedModelAdminToField( "The field %s cannot be referenced." % to_field) model = self.model opts = model._meta add = object_id is None if add: if not self.has_add_permission(request): raise PermissionDenied obj = None else: obj = self.get_object(request, unquote(object_id), to_field) if not self.has_change_permission( request, obj) and not self.has_view_permission( request, obj): raise PermissionDenied if obj is None: raise Http404( _('%(name)s object with primary key %(key)r does not exist.' ) % { 'name': force_text(opts.verbose_name), 'key': escape(object_id) }) if request.method == 'POST' and "_saveasnew" in request.POST: return self.add_view( request, form_url=reverse('admin:%s_%s_add' % (opts.app_label, opts.model_name), current_app=self.admin_site.name)) ModelForm = self.get_form(request, obj) # do not save the change if I'm not allowed to: if request.method == 'POST' and self.has_change_permission( request, obj): form = ModelForm(request.POST, request.FILES, instance=obj) if form.is_valid(): form_validated = True new_object = self.save_form(request, form, change=not add) else: form_validated = False new_object = form.instance formsets, inline_instances = self._create_formsets(request, new_object, change=not add) if all_valid(formsets) and form_validated: self.save_model(request, new_object, form, not add) self.save_related(request, form, formsets, not add) if add: self.log_addition(request, new_object) return self.response_add(request, new_object) else: change_message = self.construct_change_message( request, form, formsets) self.log_change(request, new_object, change_message) return self.response_change(request, new_object) else: if add: initial = self.get_changeform_initial_data(request) form = ModelForm(initial=initial) formsets, inline_instances = self._create_formsets( request, self.model(), change=False) else: form = ModelForm(instance=obj) formsets, inline_instances = self._create_formsets(request, obj, change=True) adminForm = helpers.AdminForm(form, list(self.get_fieldsets(request, obj)), self.get_prepopulated_fields( request, obj), self.get_readonly_fields(request, obj), model_admin=self) media = self.media + adminForm.media inline_formsets = self.get_inline_formsets(request, formsets, inline_instances, obj) for inline_formset in inline_formsets: media = media + inline_formset.media context = dict( self.admin_site.each_context(request), title=(_('Add %s') if add else _('Change %s')) % force_text(opts.verbose_name), adminform=adminForm, object_id=object_id, original=obj, is_popup=(IS_POPUP_VAR in request.POST or IS_POPUP_VAR in request.GET), to_field=to_field, media=media, inline_admin_formsets=inline_formsets, errors=helpers.AdminErrorList(form, formsets), preserved_filters=self.get_preserved_filters(request), ) context.update(extra_context or {}) return self.render_change_form(request, context, add=add, change=not add, obj=obj, form_url=form_url)
def change_view(self, request, object_id, **kwargs): # TODO raise404, here and everywhere bill = self.get_object(request, unquote(object_id)) actions.validate_contact(request, bill, error=False) return super().change_view(request, object_id, **kwargs)
def delete_view(self, request, object_id, extra_context=None): """ This method overrides the 'delete' admin view. Changes include handling exceptions raised while deleting a model and displaying the exception message to the user in a readable format instead of showing the exception page to the user """ opts = self.model._meta app_label = opts.app_label to_field = request.POST.get(TO_FIELD_VAR, request.GET.get(TO_FIELD_VAR)) if to_field and not self.to_field_allowed(request, to_field): raise DisallowedModelAdminToField( "The field %s cannot be referenced." % to_field) obj = self.get_object(request, unquote(object_id), to_field) if not self.has_delete_permission(request, obj): raise PermissionDenied if obj is None: raise Http404( _('%(name)s object with primary key %(key)r does not exist.') % { 'name': force_text(opts.verbose_name), 'key': escape(object_id) }) using = router.db_for_write(self.model) # Populate deleted_objects, a data structure of all related objects that # will also be deleted. (deleted_objects, model_count, perms_needed, protected) = get_deleted_objects([obj], opts, request.user, self.admin_site, using) if request.POST: # The user has already confirmed the deletion. if perms_needed: raise PermissionDenied obj_display = force_text(obj) attr = str(to_field) if to_field else opts.pk.attname obj_id = obj.serializable_value(attr) # start: base changes try: self.delete_model(request, obj) except Exception as e: return self.response_delete(request, obj_display, obj_id, msg=e.message, msg_type=messages.ERROR) self.log_deletion(request, obj, obj_display) # end: base changes return self.response_delete(request, obj_display, obj_id) object_name = force_text(opts.verbose_name) if perms_needed or protected: title = _("Cannot delete %(name)s") % {"name": object_name} else: title = _("Are you sure?") context = dict( self.admin_site.each_context(request), title=title, object_name=object_name, object=obj, deleted_objects=deleted_objects, model_count=dict(model_count).items(), perms_lacking=perms_needed, protected=protected, opts=opts, app_label=app_label, preserved_filters=self.get_preserved_filters(request), is_popup=(IS_POPUP_VAR in request.POST or IS_POPUP_VAR in request.GET), to_field=to_field, ) context.update(extra_context or {}) return self.render_delete_form(request, context)
def obj_perms_manage_user_view(self, request, object_pk, user_id): return super().obj_perms_manage_user_view(request, unquote(object_pk), user_id)
def clone_view(self, request, object_id, form_url='', extra_context=None): opts = self.model._meta if not self.has_add_permission(request): raise PermissionDenied original_obj = self.get_object(request, unquote(object_id)) if original_obj is None: raise Http404( _('{name} object with primary key {key} does not exist.'. format(name=force_text(opts.verbose_name), key=repr(escape(object_id))))) ModelForm = self.get_form(request) formsets = [] if request.method == 'POST': form = ModelForm(request.POST, request.FILES) if form.is_valid(): new_object = self.save_form(request, form, change=False) form_validated = True else: new_object = self.model() form_validated = False prefixes = {} for FormSet, inline in self.get_formsets_with_inlines(request): try: 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_object, save_as_new="_saveasnew" in request.POST, # ???? prefix=prefix) formsets.append(formset) except Exception as e: print(e, "!!!!") if all_valid(formsets) and form_validated: # if original model has any file field, save new model # with same paths to these files for name in vars(original_obj): field = getattr(original_obj, name) if isinstance(field, FieldFile) and name not in request.FILES: setattr(new_object, name, field) self.save_model(request, new_object, form, False) self.save_related(request, form, formsets, False) try: self.log_addition(request, new_object) except TypeError: # In Django 1.9 we need one more param self.log_addition(request, new_object, "Cloned object") return self.response_add(request, new_object, None) else: initial = model_to_dict(original_obj) initial = self.tweak_cloned_fields(initial) form = ModelForm(initial=initial) 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]) initial = [] queryset = inline.get_queryset(request).filter( **{FormSet.fk.name: original_obj}) for obj in queryset: initial.append( model_to_dict( obj, exclude=[obj._meta.pk.name, FormSet.fk.name])) initial = self.tweak_cloned_inline_fields(prefix, initial) formset = FormSet(prefix=prefix, initial=initial) # Since there is no way to customize the `extra` in the constructor, # construct the forms again... # most of this view is a hack, but this is the ugliest one formset.extra = len(initial) + formset.extra # _construct_forms() was removed on django 1.6 # see https://github.com/django/django/commit/ef79582e8630cb3c119caed52130c9671188addd if hasattr(formset, '_construct_forms'): formset._construct_forms() formsets.append(formset) 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 = [] for inline, formset in zip(self.get_inline_instances(request), formsets): fieldsets = list(inline.get_fieldsets(request, original_obj)) readonly = list(inline.get_readonly_fields(request, original_obj)) prepopulated = dict( inline.get_prepopulated_fields(request, original_obj)) inline_admin_formset = InlineAdminFormSetFakeOriginal( inline, formset, fieldsets, prepopulated, readonly, model_admin=self) inline_admin_formsets.append(inline_admin_formset) media = media + inline_admin_formset.media title = u'{0} {1}'.format(self.clone_verbose_name, opts.verbose_name) 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, formsets), 'app_label': opts.app_label, } context.update(extra_context or {}) return self.render_change_form(request, context, form_url=form_url, change=False)
def admin_unquote(obj): return unquote(obj)
def groot_view(self, request, object_id): # Only allow superusers to edit permissions if not request.user.is_superuser: raise PermissionDenied model = self.model opts = model._meta obj = self.get_object(request, unquote(object_id)) if obj is None: raise Http404( _('%(name)s object with primary key %(key)r does not exist.') % { 'name': force_text(opts.verbose_name), 'key': escape(object_id), }) opts = self.model._meta app_label = opts.app_label group_list = Group.objects.all() group_count = group_list.count() GroupPermissionForm = get_group_permission_form( model_perms=get_perms_for_model(model)) GroupPermissionFormSet = formset_factory(GroupPermissionForm, extra=0, min_num=group_count, validate_min=True, max_num=group_count) obj_group_perms = get_groups_with_perms(obj=obj, attach_perms=True) initial_data = [] for group in group_list: try: group_perms = obj_group_perms[group] except KeyError: group_perms = [] group_initial = { 'group': group, } for perm in group_perms: field_name = '%s%s' % (PERM_PREFIX, perm) group_initial[field_name] = True initial_data.append(group_initial) formset = GroupPermissionFormSet(request.POST or None, initial=initial_data) if formset.is_valid(): # The user has confirmed the update group_count = 0 for form in formset.forms: # Only act on changed data if form.has_changed(): group_count += 1 for field in form.changed_data: group = form.cleaned_data['group'] changed_perm = field.replace(PERM_PREFIX, '', 1) add_perm = form.cleaned_data[field] # Change perm action accordingly if add_perm: update_perm = assign_perm else: update_perm = remove_perm update_perm(perm=changed_perm, user_or_group=group, obj=obj) if group_count: self.message_user( request, _(('Successfully updated permissions for %(count)d %(groups)s.' )) % { 'count': group_count, 'groups': model_ngettext(Group, n=group_count), }, messages.SUCCESS) else: self.message_user(request, _('No permissions were updated.'), messages.INFO) return HttpResponseRedirect(request.path) if django.VERSION >= (1, 8): context = self.admin_site.each_context(request) else: context = self.admin_site.each_context() context.update({ 'title': _('Group permissions: %s') % force_text(obj), 'object': obj, 'opts': opts, 'formset': formset, 'group_formsets': zip(group_list, formset.forms), }) request.current_app = self.admin_site.name template_name = getattr(self, 'group_permissions_template', None) or [ 'admin/%s/%s/group_permissions.html' % (app_label, opts.model_name), 'admin/%s/group_permissions.html' % app_label, 'admin/group_permissions.html' ] # Display the form page return TemplateResponse(request, template_name, context)