Commit 55db18f2 authored by Serge S. Koval's avatar Serge S. Koval

Model admin is working.

parent 24115621
from flask import Flask
from flaskext.sqlalchemy import SQLAlchemy
from flask.ext import adminex
from flask.ext.adminex.ext import sqlamodel
# 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 model
class User(db.Model):
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(80), unique=True)
email = db.Column(db.String(120), unique=True)
def __unicode__(self):
return self.username
def __repr__(self):
return '<User %r>' % self.username
class Post(db.Model):
id = db.Column(db.Integer, primary_key=True)
title = db.Column(db.String(120))
text = db.Column(db.Text)
user_id = db.Column(db.Integer, db.ForeignKey(User.id))
user = db.relationship(User, backref='posts')
# Flask routes
@app.route('/')
def index():
return '<a href="/admin/">Click me to get to Admin!</a>'
if __name__ == '__main__':
# Create admin
admin = adminex.Admin()
admin.add_view(sqlamodel.ModelView(User, db.session, category='News'))
admin.add_view(sqlamodel.ModelView(Post, db.session, category='News'))
admin.apply(app)
# Create DB
db.create_all()
# Start app
app.debug = True
app.run()
......@@ -200,8 +200,5 @@ class Admin(object):
category.add_child(self.MenuItem(v.name, v))
print repr(self._menu)
def menu(self):
return self._menu
from sqlalchemy.orm.properties import RelationshipProperty, ColumnProperty
from sqlalchemy.orm.interfaces import MANYTOONE
from sqlalchemy import exc
from wtforms.ext.sqlalchemy.orm import model_form, ModelConverter
from wtforms.ext.sqlalchemy.fields import QuerySelectField
......@@ -45,12 +46,21 @@ class AdminModelConverter(ModelConverter):
class ModelView(BaseView):
def __init__(self, session, model, name=None, endpoint=None, url=None,
def __init__(self, model, session, name=None, category=None, endpoint=None, url=None,
can_create=True, can_edit=True, can_delete=True,
list_template='admin/model/list.html',
edit_template='admin/model/edit.html',
create_template='admin/model/edit.html'):
super(ModelView, self).__init__(name, endpoint, url)
# If name not provided, it is modelname
if name is None:
name = '%s' % self._prettify_name(model.__name__)
# If endpoint not provided, it is modelname + 'view'
if endpoint is None:
endpoint = ('%sview' % model.__name__).lower()
super(ModelView, self).__init__(name, category, endpoint, url)
self.session = session
self.model = model
......@@ -80,7 +90,7 @@ class ModelView(BaseView):
for p in mapper.iterate_properties:
if isinstance(p, RelationshipProperty):
if p.direction is MANYTOONE:
self.list_columns.append(p.key)
columns.append(p.key)
elif isinstance(p, ColumnProperty):
# TODO: Check for multiple columns
column = p.columns[0]
......@@ -99,7 +109,7 @@ class ModelView(BaseView):
return self.scaffold_form()
def scaffold_edit_form(self):
return self.scaffold_edit_form()
return self.scaffold_form()
# Database-related API
def get_list(self):
......@@ -110,6 +120,7 @@ class ModelView(BaseView):
# Model handlers
def create_model(self, form):
# TODO: Error handling
model = self.model()
form.populate_obj(model)
self.session.add(model)
......@@ -143,7 +154,7 @@ class ModelView(BaseView):
return render_template(self.create_template, view=self, form=form)
@expose('/edit/<int:id>/', methods=('GET', 'POST'))
def edit_view(self):
def edit_view(self, id):
if not self.can_edit:
return redirect(url_for('.index_view'))
......@@ -161,7 +172,7 @@ class ModelView(BaseView):
return render_template(self.edit_template, view=self, form=form)
@expose('/delete/<int:id>/')
def delete_view(self):
def delete_view(self, id):
# TODO: Use post
if not self.can_delete:
return redirect(url_for('.index_view'))
......
{% extends 'admin/master.html' %}
{% block body %}
<form action="" method="POST">
{{ form.csrf }}
<table class="form">
{% for f in form if f.label.text != 'Csrf' %}
<tr>
<td>
{{ f.label }}
</td>
<td>
{{ f }}
</td>
</tr>
{% endfor %}
<tr>
<td>
</td>
<td>
{% if form.errors %}
<ul>
{% for fn, fe in form.errors.items() if fe %}
{% for e in fe %}
<li>{{ e }}</li>
{% endfor %}
{% endfor %}
</ul>
{% endif %}
<input type="submit" class="btn btn-primary btn-large" />
</td>
</tr>
</table>
</form>
{% endblock %}
{% extends 'admin/master.html' %}
{% block body %}
<table class="table table-striped table-bordered">
<thead>
<tr>
<th></th>
{% for c in view.list_columns %}
<th>{{ c }}</th>
{% endfor %}
</tr>
</thead>
{% for row in data %}
<tr>
<td>
{% if view.can_edit %}<a href="{{ url_for('.edit_view', id=row.id) }}">Edit</a>{% endif %}
{% if view.can_delete %}<a href="{{ url_for('.delete_view', id=row.id) }}">Delete</a>{% endif %}
</td>
{% for c in view.list_columns %}
<td>{{ row[c] }}</td>
{% endfor %}
</tr>
{% endfor %}
</table>
{% if view.can_create %}
<a class="btn btn-primary btn-large" href="{{ url_for('.create_view') }}">Create New</a>
{% endif %}
{% endblock %}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment