Sie müssen Ihre Logik wenn möglich leicht ändern. Was Sie brauchen, ist benutzerdefinierte AdminModel.form
. Alle Validierung sollte dort erfolgen. Siehe Hinweis für save_model()
:
ModelAdmin.save_model() und ModelAdmin.delete_model() muss speichern/löschen das Objekt, sie sind nicht für Veto Zwecke, sondern sie ermöglichen es Ihnen, zusätzliche Operationen ausführen.
Aber wenn Ihre Umstände sind so, dass Sie nicht alle Validierung in der Form tun kann ich ModelAdmin
Unterklasse würde, und überschreiben def add_view()
, def change_view()
und def changelist_view()
wie so:
from django.contrib import admin
from django import forms
from django.contrib.admin import helpers
from django.contrib.admin.options import csrf_protect_m, IS_POPUP_VAR
from django.utils.translation import ugettext as _
from django.utils.encoding import force_text
# for nonfield errors to show correctly
from django.forms.forms import NON_FIELD_ERRORS
from .models import TestModel
class TestModelAdmin(admin.ModelAdmin):
def save_model(self, request, obj, form, change):
raise Exception('test exception')
@csrf_protect_m
def add_view(self, request, form_url='', extra_context=None):
try:
return super(TestModelAdmin, self).add_view(request, form_url, extra_context)
except Exception as e:
pass
# mimic parent class on error
model = self.model
opts = model._meta
ModelForm = self.get_form(request)
formsets = []
inline_instances = self.get_inline_instances(request, None)
form = ModelForm(request.POST, request.FILES)
form.is_valid()
# make faked nonfield error
# see http://stackoverflow.com/questions/8598247/how-to-append-error-message-to-form-non-field-errors-in-django
form._errors[NON_FIELD_ERRORS] = form.error_class([e.message])
# We may handle exception here (just to save indentation)
adminForm = helpers.AdminForm(form, list(self.get_fieldsets(request)),
self.get_prepopulated_fields(request),
self.get_readonly_fields(request),
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))
readonly = list(inline.get_readonly_fields(request))
prepopulated = dict(inline.get_prepopulated_fields(request))
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
context = {
'title': _('Add %s') % force_text(opts.verbose_name),
'adminform': adminForm,
'is_popup': IS_POPUP_VAR in request.REQUEST,
'media': media,
'inline_admin_formsets': inline_admin_formsets,
'errors': helpers.AdminErrorList(form, formsets),
'app_label': opts.app_label,
'preserved_filters': self.get_preserved_filters(request),
}
context.update(extra_context or {})
return self.render_change_form(request, context, form_url=form_url, add=True)
admin.site.register(TestModel, TestModelAdmin)
Mein models.py
:
from django.db import models
class TestModel(models.Model):
text = models.TextField()
Sie sehen, es gibt keine einfache Möglichkeit zum Einhängen innerhalb save_model()
, so dass Sie Teil kopieren müssen Formularvorbereitungscode.
'Preis außerhalb der Kunden angefordert range' ist: Können Sie die Modelle zeigen (und die Einschränkung von Ihnen angegebenen) – karthikr
Ich bin auf der Suche nach etwas mehr Generika, die für jedes Modell funktioniert/Zwang. – keithhackbarth