2015-08-19 6 views
5

Mein SQLAlchemy-Modell hat ein String Feld, das ich gerne auf ein paar Möglichkeiten beschränken würde.Limit-Optionen mit Drop-Down in Flaschen-Admin

Ich frage mich, wie ich ein Dropdown für dieses Feld in der Flask-Admin-Schnittstelle erstellen könnte, die sicherstellen würde, dass die Datenbank nur mit einer meiner Auswahlmöglichkeiten bestückt ist. Wenn ich die Benutzer manuell diese Felder eingeben lassen, können sie sie nicht richtig buchstabieren usw.

Antwort

15

enum, form_choices und form_args

Ihre Frage zu ist Wert auf Formularebene zu beschränken, aber wir können auch diskutieren sie kurz an die Schemalebene.

A. Beschränkung Werte auf Datenbankebene: enum Felder

den Bereich der zulässigen Werte zu begrenzen, das erste, was zu prüfen ist, ob Sie die Datenbank, dass vielleicht gefallen für Sie zu erzwingen. Die meisten Datenbanken haben ein Feld enum Typ, mit dem Sie ein Feld auf eine Reihe von Werten (MySQL, PostGres) beschränken können. Dieser Ansatz hat Vor- und Nachteile. Bei den Widersprüchen sind die Werte möglicherweise nicht in der von Ihnen erwarteten Reihenfolge aufgeführt. Und jedes Mal, wenn Sie dem Set neue Werte hinzufügen möchten, müssen Sie die Datenbank ändern.

B. Beschränken Werte mit Drop-downs: form_choices

Drop-downs zu erstellen, die einen Satz von zulässigen Werten darstellen, schaffen sie eine angepasste Modelview und definieren Ihren Wertebereich in form_choices. Zum Beispiel:

class FilmAdmin(sqla.ModelView): 

    form_choices = { 'now_showing': [ ('0', 'Not Showing'), ('1', 'Showing')], 
        'color': [('bw', 'Black & White'), ('color', 'Color')] 
        } 

    # (many other customizations can go here) 

In form_choices haben Sie Drop-downs erstellt für zwei Felder: now_showing und color. Das erste Feld gibt die Werte 0 und 1, aber es angenehmer für die Augen zu machen, die Form zeigen nicht Zeige für 0 und Zeige für 1.

Beachten Sie, dass dies in einer normalen Form funktioniert, aber nicht in einem Inline-Formular.

Sie müssen die Modelview zu der App hinzuzufügen: so etwas wie

admin.add_view(FilmAdmin(yourmodels.Film, db.session))

C. Validierung: form_args

In Inline-Formen, können Sie nicht auf den Dropdown-haben. Sie können jedoch Ihre benutzerdefinierte ModelView weiter verfeinern, indem Sie WTF-Validatoren für verschiedene Felder definieren.

Wie bei form_choices können Sie ein form_args Wörterbuch mit einer validators Liste definieren. Zum Beispiel:

# first import the `AnyOf` validator: 
from wtforms.validators import AnyOf 

class FilmAdmin(sqla.ModelView): 

    # column_exclude_list = ... 
    # form_excluded_columns = ... 
    # form_choices = ... 

    form_args = { 
     'flavors': { 
      'validators': [AnyOf(['strawberry', 'chocolate'])] 
     } 
    } 

Es gibt viele vordefinierte Validatoren, und Sie können Ihre eigenen definieren: entnehmen Sie bitte dem flask-admin introduction und zum validators section of the WTF documentation.

+0

Wahl "A" wurde ursprünglich verwendet, obwohl es eine Vielzahl von Alpträumen schafft (wie Sie erwähnten). Also habe ich es in ein String-Feld geändert und die Einträge in den Controllern eingeschränkt. –

+0

Ja, es gibt eine Zeit und einen Ort für 'enum'. Der Speicher ist kleiner mit 'enum' (nur eine Kopie des Wertes), aber Lookup/Joining kann langsamer sein (diskutiert auf S.123-124 von * High-Performance MySQL *, 3. Ausgabe. Es ist eine gute Frage, hoffe es für andere hilfreich sein :) – zx81

+0

Übrigens scheint es einen [Fehler mit 'enum' Feldern in flask-admin] (https://github.com/flask-admin/flask-admin/issues/1003) zu geben könnte sein, was du erlebt hast. Momentan hat der flask-admin eine Menge [ungelöste Probleme, die nicht so gering sind] (https://github.com/flask-admin/flask-admin/issues) (siehe die Sicherheitssache # 1000 und andere). . Sie würden denken, dass bis 2015 das Problem der Erstellung von Admin-Schnittstellen gelöst werden würde, aber überhaupt nicht. Ich habe die Silberkugel nicht gefunden, abgesehen davon, dass ich mir die Zeit genommen habe, die ganze Sache mit der Hand zu codieren, was mir auch die schrecklich ineffiziente ORM – zx81