2014-04-08 20 views
6

Ich studiere Flask-Admin kombiniert mit PeeWee Backend Modelview (aber meine Frage kann auch auf SQLAlchemy Backend angewendet werden), und es gibt zwei Dinge, die ich nicht in der Dokumentation oder Beispiele finden konnten:Flask-Admin ModelView benutzerdefinierte Validierung?

(1). Wenn mein Modell ein eindeutiges Feld hat und ich es versuche/versuche, es zu duplizieren, bekomme ich einen standardmäßigen Flasch-Absturzbildschirm mit der Meldung: "IntegrityError: Spaltenbenutzername ist nicht eindeutig"

Ich teste das verfügbare PeeWee-Beispiel in https://github.com/mrjoes/flask-admin/blob/master/examples/peewee/simple.py, und ich änderte die Zeile 21 in "username = peewee.CharField (max_length = 80, unique = True)"

Dann versuche ich zwei Benutzer mit "username" = "user1" hinzuzufügen.

Gibt es einen höflichen Weg, um zum Bearbeitungsbildschirm zurückzukehren (oder sogar den Listenbildschirm, würde jeder Admin-Bildschirm tun), aber mit einer kontrollierten Fehlermeldung? Ich brauche keine benutzerdefinierte Fehlermeldung, aktuelle Nachricht ist in Ordnung (IntegrityError: Spalte Benutzername ist nicht eindeutig). Aber ich will den Crash-Bildschirm nicht.

Ich könnte Flasks Standard-500-Seite einrichten/verwenden, aber dann würde ich den Flask-Admin-Ablauf vollständig beenden und der Benutzer würde die Daten, die er gerade eingegeben hat, "vermissen".

Ich möchte zurück zum Bearbeitungsbildschirm, aber mit einer Art Warnung/Fehlermeldung. Es macht mir nichts aus, die Vorlagen zu erweitern, das ist kein Problem. Aber ich konnte keinen Ort finden, um den Fehler abzufangen und richtig zu behandeln. Irgendwelche Vorschläge?

und (2):

Ich brauche auch einen Weg, um einige Pre-Save-Validierung in der Strömung hinzuzufügen. Zum Beispiel bin ich in einer Bearbeitungsform einer Entität, die initial_date und final_date hat, und ich möchte sicherstellen, dass final_date größer als initial_date ist oder null ist, bevor Sie speichern.

Ich könnte dies clientseitig über Javascript machen, indem ich die Bearbeitungsvorlage für diese Entität erweitere und mein Validierungsskript im Endblock hinzufüge (und das form.submit-Ereignis abfange).

Aber was ist, wenn meine Validierung eine serverseitige Validierung in letzter Minute erfordert? Gibt es eine Möglichkeit/einen Ort, um den Fluss abzufangen und meine Validierung hinzuzufügen, und mit etwas Glück meine Fehlermeldung auf die gleiche Weise zurück zu werfen, wie in Frage 1 beschrieben?

Vielen Dank im Voraus,

Grüßen,

+0

Grund, warum es abstürzt - Flask-Admin wird alle Ausnahmen (sogar IntegrityError) erneut auslösen, wenn Flask im Debug-Modus läuft. Ich werde die IntegrityError-Behandlung als Ausnahme zu dieser Regel hinzufügen. pre-save kann in der Form oder in 'on_model_change' erfolgen - Sie können Ausnahme von dort auslösen. Während die Ausnahme mit dem Werkzeug Debugger angezeigt wird, wird im Produktionsmodus eine Fehlermeldung angezeigt. – Joes

+0

@Joes 'on_model_change' ist ein Post-Save-Hook, wie in der Dokumentation erwähnt:" Führe einige Aktionen aus ** nachdem ** ein Modell erstellt oder aktualisiert wurde. "Es gibt keinen Pre-Save-Hook in Flask admin AFAIK Die Basisformklasse und die Anpassung in der Unterklasse stellen die einzige Möglichkeit zur Beantwortung der Frage von OP dar. – Devy

+0

@Devy 'on_model_change' wird aufgerufen, wenn das Modell mit Formulardaten aktualisiert wurde, aber bevor die Sitzung an die Datenbank übergeben wurde – Joes

Antwort

11

Ich glaube, ich habe ein paar Dinge gefunden, die helfen, aber completelly meine Frage nicht beantwortet.

ich gepostet ein Beispiel auf Pastebin: http://pastebin.com/siwiaJAw

zuerst, ich nicht ‚vor retten‘ Schritt finden konnte, aber ich habe festgestellt, wie auf Feldebene benutzerdefinierte Validierung hinzufügen, die schafft in den Fällen hilft der und Updates.

Wenn Sie das Beispiel überprüfen, werden Sie Linien sehen 37-39 und 42-44, wo ich hinzugefügt:

def no_root_allowed(form, field): 
    if field.data == 'root': 
     raise ValidationError('"root" is not allowed') 

form_args = dict(
    username=dict(validators=[no_root_allowed]) 
) 

Diese Prüfung erhält ‚Form‘ und ‚Feld‘ und so kann ich Validierungen tun, dass involvieren mehr als ein Feld (wie Startdatum < Enddatum), und ich kann wahrscheinlich sogar auf die Model-Klassen zugreifen, um zum Beispiel nach ID-Duplizierung zu suchen.

So, das löst die Erstellung/Bearbeitung Validierung. Wenn der Validierer fehlschlägt, bringt Flask-Admin mich zurück zum bearbeiteten Formular. Nett!

Aber es gibt ein Problem mit Löschungen. Wenn ich nicht möchte, dass ein bestimmtes Objekt gelöscht wird, kann ich es als can_delete = False markieren, aber das würde verhindern, dass eine Instanz gelöscht wird.

Das Beste, was ich finden konnte, war die delete_model-Methode (Zeile 55) abzufangen und False im Falle eines Pre-Delete-Validierung fehlschlagen. Aber das würde keine Nachricht aufkommen lassen und würde mich nur zum Formular zurückbringen. Ich konnte keine Möglichkeit finden, dem Benutzer eine Nachricht zu senden, dass er diese bestimmte Instanz nicht löschen konnte.

Ich werde weiter studieren und werde weitere Nachrichten posten.

danke!

+0

Dank einer TON für das Posten dieser. Sparte mir viel Zeit zu graben. – Chrispy

+0

Wissen Sie, ob es für einen benutzerdefinierten Validator möglich ist zu sagen, ob es ein vorhandenes Modell aktualisiert oder ein neues erstellt? is_created Attribut? – Chrispy

Verwandte Themen