2010-02-01 8 views
14

Ich habe ein Buchungsmodell, das prüfen muss, ob der ausgebuchte Artikel verfügbar ist. Ich hätte gerne die Logik dahinter, herauszufinden, ob das Objekt zentral verfügbar ist, so dass dieser Code unabhängig davon, wo ich die Instanz speichere, validiert, dass er gespeichert werden kann.Anzeigen von Ausnahmen für benutzerdefinierte Modellüberprüfung in der Django-Verwaltungssite

Im Moment habe ich diesen Code in einem benutzerdefinierten Speicherfunktion meiner Modellklasse:

def save(self): 
    if self.is_available(): # my custom check availability function 
     super(MyObj, self).save() 
    else: 
     # this is the bit I'm stuck with.. 
     raise forms.ValidationError('Item already booked for those dates') 

Dies funktioniert gut - der Fehler wird ausgelöst, wenn das Element nicht verfügbar ist, und mein Artikel wird nicht gespeichert. Ich kann die Ausnahme von meinem Frontend-Formularcode erfassen, aber was ist mit der Django-Verwaltungsseite? Wie kann ich meine Ausnahme wie jeden anderen Validierungsfehler auf der Verwaltungsseite anzeigen lassen?

Antwort

9

Hier gehts: http://docs.djangoproject.com/en/dev/ref/contrib/admin/#adding-custom-validation-to-the-admin Dies könnte jedoch orthogonal zu dem Weg, den Sie genommen haben. Dies sollte kein Validierungsfehler sein, dass Sie steigen, weil diese von Formularen ausgelöst werden. Wie auch immer, schauen Sie sich um und wählen Sie, wie Sie möchten.

+1

Ich glaube, ich wollte an einem Ort zu schreiben, etwas, das, dass eine Instanz konnte nicht gespeichert werden sichergestellt, dass meine Validierungsregeln brach - Da die Speicherfunktion unabhängig davon aufgerufen wird, wo Sie speichern (Admin oder Frontend), ist es sinnvoll, sie dort anzulegen. –

+0

Ja, aber ValidationError wird verwendet, um den Endbenutzer darüber zu informieren, dass die Informationen, die er in ein Formular eingibt, falsch sind. Wenn Sie sicherstellen müssen, dass einige Regeln eingehalten werden, sollten Sie vielleicht eine Assertion verwenden? Oder, wenn speichern kann einfach scheitern, als vielleicht sollten Sie einfach einen Return-Code, ob es richtig gespeichert wurde. Ich weiß nicht, was genau du brauchst. – gruszczy

+0

Dieser Link antwortet ihm überhaupt nicht. Er möchte die Validierung in seinem Modell in Admin wiederverwenden. Nicht die Validierung in Admin neu zu implementieren ... – Cerin

2

Ich habe auch versucht, dies zu lösen und es gibt meine Lösung - in meinem Fall musste ich Änderungen in related_objects verweigern, wenn das main_object für die Bearbeitung gesperrt ist.

1) benutzerdefinierte Ausnahme

class Error(Exception): 
    """Base class for errors in this module.""" 
    pass 

class EditNotAllowedError(Error): 
    def __init__(self, msg): 
     Exception.__init__(self, msg) 

2) metaclass mit benutzerdefinierten speichern Methoden- alle meine related_data Modelle auf dieser Grundlage wird:

class RelatedModel(models.Model): 
    main_object = models.ForeignKey("Main") 

    class Meta: 
     abstract = True 

    def save(self, *args, **kwargs): 
     if self.main_object.is_editable(): 
      super(RelatedModel, self).save(*args, **kwargs) 
     else: 
      raise EditNotAllowedError, "Closed for editing" 

3) metaform - alle meine related_data Admin-Formulare werden basiert darauf (es stellt sicher, dass die Admin - Schnittstelle den Benutzer ohne den Fehler der Administrationsoberfläche informiert):

In meinen Augen ist es nicht so viel Overhead und immer noch ziemlich einfach und wartbar.

17

In django 1.2 wurde die Modellvalidierung hinzugefügt.

Sie können Ihren Modellen nun eine "clean" -Methode hinzufügen, die ValidationError-Ausnahmen auslöst, und sie wird automatisch aufgerufen, wenn der django admin verwendet wird.

(Es ist nicht ganz klar, in der Dokumentation, die die saubere Methode durch den Admin genannt wird, aber ich habe es hier verifiziert)

http://docs.djangoproject.com/en/dev/ref/models/instances/?from=olddocs#validating-objects

So Ihre saubere Methode so etwas wie dies sein könnte:

from django.core.exceptions import ValidationError 

class MyModel(models.Model): 

    def is_available(self): 
     #do check here 
     return result 

    def clean(self): 
     if not self.is_available(): 
      raise ValidationError('Item already booked for those dates') 

ich habe keinen Gebrauch davon ausgiebig gemacht, aber scheint, wie viel weniger Code als ein Modelform zu schaffen haben, und verknüpfen sie dann diese Form in der admin.py-Datei zur Verwendung in django admin ein.

+1

Was passiert, wenn 'save()' immer noch eine Exception auslöst? – spinkus

+0

Das ist, was ich in den letzten 3 Stunden gesucht habe! Danke! – kchomski

2

Ziemlich alte Post, aber ich denke, "benutzerdefinierte Reinigung verwenden" ist immer noch die akzeptierte Antwort. Aber es ist nicht befriedigend. Sie können so viele Vorabprüfungen vornehmen, wie Sie möchten, dass Sie dennoch eine Ausnahme in Model.save() erhalten, und Sie können eine Nachricht an den Benutzer in einer Weise anzeigen, die mit einem Formularüberprüfungsfehler konsistent ist.

Die Lösung, die ich fand, war zu überschreiben ModelAdmin.changeform_view().In diesem Fall fangen Ich bin ein Integritätsfehler irgendwo in der SQL-Treiber generiert:

def changeform_view(self, request, object_id=None, form_url='', extra_context=None): 
    try: 
     return super(MyModelAdmin, self).changeform_view(request, object_id, form_url, extra_context) 
    except IntegrityError as e: 
     self.message_user(request, e, level=messages.ERROR) 
     return HttpResponseRedirect(form_url) 
+0

Damit es funktioniert, müssen Sie importieren: 'from django.contrib import messages' und' from django.http import HttpResponseRedirect'. –

Verwandte Themen