Skip to content

Instantly share code, notes, and snippets.

@mrjoes
Created May 5, 2013 17:49
Show Gist options
  • Save mrjoes/5521548 to your computer and use it in GitHub Desktop.
Save mrjoes/5521548 to your computer and use it in GitHub Desktop.
How to customize options in QuerySelectField. High level idea: 1. Hook `create_form` to change options when creating model and `edit_form` when editing model 2. Provide different `query_factory` for the field 3. Do filtering/population logic in the _get_parent_list Alternatively: 1. Can hook `scaffold_form` and change `form.parent.kwargs['query_…
from flask import Flask, request, url_for
from flask.ext.sqlalchemy import SQLAlchemy
from flask.ext.admin.contrib import sqlamodel
from flask.ext import admin
# Create application
app = Flask(__name__)
# Create dummy secrey key so we can use sessions
app.config['SECRET_KEY'] = '123456790'
# Create in-memory database
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///test.sqlite'
app.config['SQLALCHEMY_ECHO'] = True
db = SQLAlchemy(app)
# Create models
class Parent(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(120))
def __unicode__(self):
return self.name
class Child(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.Unicode(64))
parent_id = db.Column(db.Integer(), db.ForeignKey(Parent.id), nullable=False)
parent = db.relationship(Parent, backref='children')
def __unicode__(self):
return self.name
# Flask views
@app.route('/')
def index():
return '<a href="/admin/">Click me to get to Admin!</a>'
# Customized Post model admin
class ChildAdmin(sqlamodel.ModelView):
# Hook form creation methods
def create_form(self):
return self._use_filtered_parent(super(ChildAdmin, self).create_form())
def edit_form(self, obj):
return self._use_filtered_parent(super(ChildAdmin, self).edit_form(obj))
# Logic
def _use_filtered_parent(self, form):
form.parent.query_factory = self._get_parent_list
return form
def _get_parent_list(self):
return self.session.query(Parent).filter_by(name='test').all()
if __name__ == '__main__':
# Create admin
a = admin.Admin(app, 'Simple Models')
# Add views
a.add_view(sqlamodel.ModelView(Parent, db.session))
a.add_view(ChildAdmin(Child, db.session))
# Create DB
db.create_all()
# Start app
app.debug = True
app.run('0.0.0.0', 8000)
@boolbag
Copy link

boolbag commented Sep 22, 2015

@mrjoes
Pawl suggested that this gist might be a solution to the problem of cascading fields, which I have been stuck with for a while.

On this cascading fields issue, there is a simple gist showcasing the cascading problem I am stuck with.

I have tried to adapt your gist to this problem but am missing something.

Would you consider showing a simple solution to that problem? I am sure it would benefit a number of people faced with the same issue.

In advance, many thanks.

@michael-stefanski
Copy link

Thanks for posting this answer. How would you handle larger forms? Imagine a form with 20 fields, five of which are drop downs and each one has a separate query to create the validated entries.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment