Skip to content
Browse files

Merge pull request #134 from plaes/expose_plugview

Support for nested flask.views.MethodView
  • Loading branch information...
2 parents 199ccd1 + 5c7fbde commit 73b28026d7f263126873c862204044efed5a692f @mrjoes committed Dec 24, 2012
View
3 doc/api/mod_base.rst
@@ -7,6 +7,7 @@
---------
.. autofunction:: expose
+ .. autofunction:: expose_plugview
.. autoclass:: BaseView
:members:
@@ -21,4 +22,4 @@
-----
.. autoclass:: Admin
- :members:
+ :members:
View
44 examples/methodview/methodview.py
@@ -0,0 +1,44 @@
+from flask import Flask, redirect, render_template, request
+
+from flask.ext import admin
+from flask.views import MethodView
+
+
+class ViewWithMethodViews(admin.BaseView):
+ @admin.expose('/')
+ def index(self):
+ return self.render('methodtest.html')
+
+ @admin.expose_plugview('/_api/1')
+ class API_v1(MethodView):
+ def get(self, cls):
+ return cls.render('test.html', request=request, name="API_v1")
+ def post(self, cls):
+ return cls.render('test.html', request=request, name="API_v1")
+
+ @admin.expose_plugview('/_api/2')
+ class API_v2(MethodView):
+ def get(self, cls):
+ return cls.render('test.html', request=request, name="API_v2")
+ def post(self, cls):
+ return cls.render('test.html', request=request, name="API_v2")
+
+# Create flask app
+app = Flask(__name__, template_folder='templates')
+
+
+# Flask views
+@app.route('/')
+def index():
+ return redirect('/admin')
+
+
+if __name__ == '__main__':
+ # Create admin interface
+ admin = admin.Admin()
+ admin.add_view(ViewWithMethodViews())
+ admin.init_app(app)
+
+ # Start app
+ app.debug = True
+ app.run()
View
12 examples/methodview/templates/methodtest.html
@@ -0,0 +1,12 @@
+{% extends 'admin/master.html' %}
+{% block body %}
+ Hello World from MethodTest!<br/>
+ <form method="POST" action="{{ url_for('.API_v1') }}">
+ <input type="submit" value="API v1 via POST">
+ <a href="{{ url_for('.API_v1') }}">v1 via GET</a>
+ </form>
+ <form method="POST" action="{{ url_for('.API_v2') }}">
+ <input type="submit" value="API v2 via POST">
+ <a href="{{ url_for('.API_v2') }}">v2 via GET</a>
+ </form>
+{% endblock %}
View
7 examples/methodview/templates/test.html
@@ -0,0 +1,7 @@
+{% extends 'admin/master.html' %}
+{% block body %}
+ This view {{ name }} was accessed using {{ request.method }} request.
+
+ <br>
+ <a href="{{ url_for('.index') }}">Return</a>
+{% endblock %}
View
2 flask_admin/__init__.py
@@ -3,4 +3,4 @@
__email__ = 'serge.koval+github@gmail.com'
-from .base import expose, expose_class, Admin, BaseView, AdminIndexView
+from .base import expose, expose_plugview, Admin, BaseView, AdminIndexView
View
11 flask_admin/base.py
@@ -22,20 +22,21 @@ def wrap(f):
f._urls = []
f._urls.append((url, methods))
return f
-
return wrap
-def expose_class(url='/'):
+def expose_plugview(url='/'):
"""
- User this decorator to expose ``View`` classes (flask.MethodView).
+ Decorator to expose Flask's pluggable view classes
+ (``flask.views.View`` or ``flask.views.MethodView``).
:param url:
Relative URL for the view
+
+ .. versionadded:: 1.0.4
"""
def wrap(v):
- name = v.__name__
- return expose(url)(v.as_view(name))
+ return expose(url, v.methods)(v.as_view(v.__name__))
return wrap
View
1 flask_admin/tests/templates/method.html
@@ -0,0 +1 @@
+{{ request.method }} - {{ name }}
View
52 flask_admin/tests/test_base.py
@@ -1,6 +1,7 @@
from nose.tools import ok_, eq_, raises
-from flask import Flask
+from flask import Flask, request
+from flask.views import MethodView
from flask.ext.admin import base
@@ -29,6 +30,28 @@ def is_accessible(self):
else:
return False
+class MockMethodView(base.BaseView):
+ @base.expose('/')
+ def index(self):
+ return 'Success!'
+
+ @base.expose_plugview('/_api/1')
+ class API1(MethodView):
+ def get(self, cls):
+ return cls.render('method.html', request=request, name='API1')
+ def post(self, cls):
+ return cls.render('method.html', request=request, name='API1')
+ def put(self, cls):
+ return cls.render('method.html', request=request, name='API1')
+ def delete(self, cls):
+ return cls.render('method.html', request=request, name='API1')
+
+ @base.expose_plugview('/_api/2')
+ class API2(MethodView):
+ def get(self, cls):
+ return cls.render('method.html', request=request, name='API2')
+ def post(self, cls):
+ return cls.render('method.html', request=request, name='API2')
def test_baseview_defaults():
view = MockView()
@@ -229,3 +252,30 @@ def test_double_init():
app = Flask(__name__)
admin = base.Admin(app)
admin.init_app(app)
+
+def test_nested_flask_views():
+ app = Flask(__name__)
+ admin = base.Admin(app)
+
+ view = MockMethodView()
+ admin.add_view(view)
+
+ client = app.test_client()
+
+ rv = client.get('/admin/mockmethodview/_api/1')
+ assert rv.data == 'GET - API1'
+ rv = client.put('/admin/mockmethodview/_api/1')
+ assert rv.data == 'PUT - API1'
+ rv = client.post('/admin/mockmethodview/_api/1')
+ assert rv.data == 'POST - API1'
+ rv = client.delete('/admin/mockmethodview/_api/1')
+ assert rv.data == 'DELETE - API1'
+
+ rv = client.get('/admin/mockmethodview/_api/2')
+ assert rv.data == 'GET - API2'
+ rv = client.post('/admin/mockmethodview/_api/2')
+ assert rv.data == 'POST - API2'
+ rv = client.delete('/admin/mockmethodview/_api/2')
+ assert rv.status_code == 405
+ rv = client.put('/admin/mockmethodview/_api/2')
+ assert rv.status_code == 405

0 comments on commit 73b2802

Please sign in to comment.
Something went wrong with that request. Please try again.