Commit b255126b authored by Serge S. Koval's avatar Serge S. Koval

Get rid of flask-wtf dependency

parent 16b254d1
- Core
- View Site button?
- Localization
- Create documentation
- Model Admin
- Simplify scaffold_list_columns - remove excluded_list_columns check, update documentation
- Simplify InlineModelFormList implementation - accept property instead of property name
- Reduce number of parameters passed to list view
- Filters
- Use table to draw filters so column names will line up?
- Change boolean filter to True/False instead of Yes/No
- Ability to sort by fields that are not visible?
- List display callables?
- MongoEngine
- EmbeddedDocument customization
- File admin
- Header title
- File size restriction
- Unit tests
- Form generation tests
- Documentation
- Add all new stuff
- Fixed stylesheet
- Python 3
- Test for raw wtforms form
......@@ -15,9 +15,9 @@ with PyMongo:
This is minimal PyMongo view::
class UserForm(wtf.Form):
name = wtf.TextForm('Name')
email = wtf.TextForm('Email')
class UserForm(Form):
name = TextField('Name')
email = TextField('Email')
class UserView(ModelView):
column_list = ('name', 'email')
......
......@@ -97,7 +97,7 @@ you can do something like this::
class UserView(ModelView):
def scaffold_form(self):
form_class = super(UserView, self).scaffold_form()
form_class.extra = wtf.TextField('Extra')
form_class.extra = TextField('Extra')
return form_class
Check :doc:`api/mod_contrib_sqlamodel` documentation for list of
......
......@@ -163,7 +163,7 @@ Steps to add new model backend:
class MyDbModel(BaseModelView):
def scaffold_form(self):
class MyForm(wtf.Form):
class MyForm(Form):
pass
# Do something
......
......@@ -24,5 +24,5 @@ field. In this case, you need to manually contribute field::
class MyView(ModelView):
def scaffold_form(self):
form_class = super(UserView, self).scaffold_form()
form_class.extra = wtf.TextField('Extra')
form_class.extra = TextField('Extra')
return form_class
from flask import Flask, url_for, redirect, render_template, request
from flask.ext.mongoengine import MongoEngine
from flask.ext import admin, login, wtf
from wtforms import form, fields, validators
from flask.ext import admin, login
from flask.ext.admin.contrib.mongoengine import ModelView
# Create application
......@@ -42,31 +44,31 @@ class User(db.Document):
# Define login and registration forms (for flask-login)
class LoginForm(wtf.Form):
login = wtf.TextField(validators=[wtf.required()])
password = wtf.PasswordField(validators=[wtf.required()])
class LoginForm(form.Form):
login = fields.TextField(validators=[validators.required()])
password = fields.PasswordField(validators=[validators.required()])
def validate_login(self, field):
user = self.get_user()
if user is None:
raise wtf.ValidationError('Invalid user')
raise validators.ValidationError('Invalid user')
if user.password != self.password.data:
raise wtf.ValidationError('Invalid password')
raise validators.ValidationError('Invalid password')
def get_user(self):
return User.objects(login=self.login.data).first()
class RegistrationForm(wtf.Form):
login = wtf.TextField(validators=[wtf.required()])
email = wtf.TextField()
password = wtf.PasswordField(validators=[wtf.required()])
class RegistrationForm(form.Form):
login = fields.TextField(validators=[validators.required()])
email = fields.TextField()
password = fields.PasswordField(validators=[validators.required()])
def validate_login(self, field):
if User.objects(login=self.login.data):
raise wtf.ValidationError('Duplicate username')
raise validators.ValidationError('Duplicate username')
# Initialize flask-login
......
from flask import Flask, url_for, redirect, render_template, request
from flask.ext.sqlalchemy import SQLAlchemy
from flask.ext import admin, login, wtf
from wtforms import form, fields, validators
from flask.ext import admin, login
from flask.ext.admin.contrib import sqlamodel
# Create Flask application
......@@ -43,31 +45,31 @@ class User(db.Model):
# Define login and registration forms (for flask-login)
class LoginForm(wtf.Form):
login = wtf.TextField(validators=[wtf.required()])
password = wtf.PasswordField(validators=[wtf.required()])
class LoginForm(form.Form):
login = fields.TextField(validators=[validators.required()])
password = fields.PasswordField(validators=[validators.required()])
def validate_login(self, field):
user = self.get_user()
if user is None:
raise wtf.ValidationError('Invalid user')
raise validators.ValidationError('Invalid user')
if user.password != self.password.data:
raise wtf.ValidationError('Invalid password')
raise validators.ValidationError('Invalid password')
def get_user(self):
return db.session.query(User).filter_by(login=self.login.data).first()
class RegistrationForm(wtf.Form):
login = wtf.TextField(validators=[wtf.required()])
email = wtf.TextField()
password = wtf.PasswordField(validators=[wtf.required()])
class RegistrationForm(form.Form):
login = fields.TextField(validators=[validators.required()])
email = fields.TextField()
password = fields.PasswordField(validators=[validators.required()])
def validate_login(self, field):
if db.session.query(User).filter_by(login=self.login.data).count() > 0:
raise wtf.ValidationError('Duplicate username')
raise validators.ValidationError('Duplicate username')
# Initialize flask-login
......
......@@ -2,12 +2,13 @@ import pymongo
from bson.objectid import ObjectId
from flask import Flask
from flask.ext import admin
from flask.ext import admin, wtf
from wtforms import form, fields
from flask.ext.admin.form import Select2Widget
from flask.ext.admin.contrib.pymongo import ModelView, filters
from flask.ext.admin.model import fields
from flask.ext.admin.model import InlineFormField, InlineFieldList
# Create application
app = Flask(__name__)
......@@ -21,21 +22,21 @@ db = conn.test
# User admin
class InnerForm(wtf.Form):
name = wtf.TextField('Name')
test = wtf.TextField('Test')
class InnerForm(form.Form):
name = fields.TextField('Name')
test = fields.TextField('Test')
class UserForm(wtf.Form):
name = wtf.TextField('Name')
email = wtf.TextField('Email')
password = wtf.TextField('Password')
class UserForm(form.Form):
name = fields.TextField('Name')
email = fields.TextField('Email')
password = fields.TextField('Password')
# Inner form
inner = fields.InlineFormField(InnerForm)
inner = InlineFormField(InnerForm)
# Form list
form_list = fields.InlineFieldList(fields.InlineFormField(InnerForm))
form_list = InlineFieldList(InlineFormField(InnerForm))
class UserView(ModelView):
......@@ -46,10 +47,10 @@ class UserView(ModelView):
# Tweet view
class TweetForm(wtf.Form):
name = wtf.TextField('Name')
user_id = wtf.SelectField('User', widget=Select2Widget())
text = wtf.TextField('Text')
class TweetForm(form.Form):
name = fields.TextField('Name')
user_id = fields.SelectField('User', widget=Select2Widget())
text = fields.TextField('Text')
class TweetView(ModelView):
......
from flask import Flask
from flask.ext.sqlalchemy import SQLAlchemy
from flask.ext import admin, wtf
from wtforms import validators
from flask.ext import admin
from flask.ext.admin.contrib import sqlamodel
from flask.ext.admin.contrib.sqlamodel import filters
......@@ -114,7 +116,7 @@ class PostAdmin(sqlamodel.ModelView):
# Pass arguments to WTForms. In this case, change label for text field to
# be 'Big Text' and add required() validator.
form_args = dict(
text=dict(label='Big Text', validators=[wtf.required()])
text=dict(label='Big Text', validators=[validators.required()])
)
def __init__(self, session):
......
from flask import Flask
from flask.ext.sqlalchemy import SQLAlchemy
from flask.ext import admin, wtf
from wtforms import fields, widgets
from flask.ext import admin
from flask.ext.admin.contrib import sqlamodel
# Create application
......@@ -17,13 +19,13 @@ db = SQLAlchemy(app)
# Define wtforms widget and field
class CKTextAreaWidget(wtf.TextArea):
class CKTextAreaWidget(widgets.TextArea):
def __call__(self, field, **kwargs):
kwargs.setdefault('class_', 'ckeditor')
return super(CKTextAreaWidget, self).__call__(field, **kwargs)
class CKTextAreaField(wtf.TextAreaField):
class CKTextAreaField(fields.TextAreaField):
widget = CKTextAreaWidget()
......
......@@ -6,16 +6,16 @@ import re
import shutil
from operator import itemgetter
from werkzeug import secure_filename
from flask import flash, url_for, redirect, abort, request
from wtforms import fields, validators
from flask.ext.admin.base import BaseView, expose
from flask.ext.admin.actions import action, ActionsMixin
from flask.ext.admin.babel import gettext, lazy_gettext
from flask.ext.admin import form
from flask.ext import wtf
class NameForm(form.BaseForm):
......@@ -24,13 +24,13 @@ class NameForm(form.BaseForm):
Validates if provided name is valid for *nix and Windows systems.
"""
name = wtf.TextField()
name = fields.TextField()
regexp = re.compile(r'^(?!^(PRN|AUX|CLOCK\$|NUL|CON|COM\d|LPT\d|\..*)(\..+)?$)[^\x00-\x1f\\?*:\";|/]+$')
def validate_name(self, field):
if not self.regexp.match(field.data):
raise wtf.ValidationError(gettext('Invalid directory name'))
raise validators.ValidationError(gettext('Invalid directory name'))
class UploadForm(form.BaseForm):
......@@ -38,7 +38,7 @@ class UploadForm(form.BaseForm):
File upload form. Works with FileAdmin instance to check if it is allowed
to upload file with given extension.
"""
upload = wtf.FileField(lazy_gettext('File to upload'))
upload = fields.FileField(lazy_gettext('File to upload'))
def __init__(self, admin):
self.admin = admin
......@@ -47,17 +47,17 @@ class UploadForm(form.BaseForm):
def validate_upload(self, field):
if not self.upload.has_file():
raise wtf.ValidationError(gettext('File required.'))
raise validators.ValidationError(gettext('File required.'))
filename = self.upload.data.filename
if not self.admin.is_file_allowed(filename):
raise wtf.ValidationError(gettext('Invalid file type.'))
raise validators.ValidationError(gettext('Invalid file type.'))
class EditForm(form.BaseForm):
content = wtf.TextAreaField(lazy_gettext('Content'),
[wtf.validators.required()])
content = fields.TextAreaField(lazy_gettext('Content'),
(validators.required(),))
class FileAdmin(BaseView, ActionsMixin):
......@@ -181,13 +181,13 @@ class FileAdmin(BaseView, ActionsMixin):
self._on_windows = platform.system() == 'Windows'
# Convert allowed_extensions to set for quick validation
if (self.allowed_extensions
and not isinstance(self.allowed_extensions, set)):
if (self.allowed_extensions and
not isinstance(self.allowed_extensions, set)):
self.allowed_extensions = set(self.allowed_extensions)
# Convert editable_extensions to set for quick validation
if (self.editable_extensions
and not isinstance(self.editable_extensions, set)):
if (self.editable_extensions and
not isinstance(self.editable_extensions, set)):
self.editable_extensions = set(self.editable_extensions)
# Check if path exists
......
......@@ -55,7 +55,7 @@ class ModelView(BaseModelView):
class MyInlineModelConverter(AdminModelConverter):
def post_process(self, form_class, info):
form_class.value = wtf.TextField('value')
form_class.value = TextField('value')
return form_class
class MyAdminView(ModelView):
......
import time
import datetime
from wtforms import fields, widgets
from wtforms import form, fields, widgets
from flask.globals import _request_ctx_stack
from flask.ext import wtf
from flask.ext.admin.babel import gettext, ngettext
from flask.ext.admin import helpers as h
class BaseForm(wtf.Form):
class BaseForm(form.Form):
"""
Customized form class.
"""
......@@ -28,7 +27,7 @@ class BaseForm(wtf.Form):
"""
# TODO: Optimize me
for f in self:
if isinstance(f, wtf.FileField):
if isinstance(f, fields.FileField):
return True
return False
......
......@@ -246,7 +246,7 @@ class BaseModelView(BaseView, ActionsMixin):
For example::
class MyForm(wtf.Form):
class MyForm(Form):
pass
class MyModelView(BaseModelView):
......@@ -262,7 +262,7 @@ class BaseModelView(BaseView, ActionsMixin):
class MyModelView(BaseModelView):
form_args = dict(
name=dict(label='First Name', validators=[wtf.required()])
name=dict(label='First Name', validators=[required()])
)
"""
......
......@@ -48,7 +48,7 @@ class InlineFormAdmin(object):
class MyInlineForm(InlineFormAdmin):
def postprocess_form(self, form):
form.value = wtf.TextField('value')
form.value = TextField('value')
return form
class MyAdmin(ModelView):
......
from nose.tools import eq_, ok_
from flask.ext import wtf
from wtforms import fields
from flask.ext.admin.contrib.mongoengine import ModelView
from . import setup
......@@ -62,14 +63,14 @@ def test_model():
# Verify form
# TODO: Figure out why there's inconsistency
try:
eq_(view._create_form_class.test1.field_class, wtf.TextField)
eq_(view._create_form_class.test2.field_class, wtf.TextField)
eq_(view._create_form_class.test1.field_class, fields.TextField)
eq_(view._create_form_class.test2.field_class, fields.TextField)
except AssertionError:
eq_(view._create_form_class.test1.field_class, wtf.StringField)
eq_(view._create_form_class.test2.field_class, wtf.StringField)
eq_(view._create_form_class.test1.field_class, fields.StringField)
eq_(view._create_form_class.test2.field_class, fields.StringField)
eq_(view._create_form_class.test3.field_class, wtf.TextAreaField)
eq_(view._create_form_class.test4.field_class, wtf.TextAreaField)
eq_(view._create_form_class.test3.field_class, fields.TextAreaField)
eq_(view._create_form_class.test4.field_class, fields.TextAreaField)
# Make some test clients
client = app.test_client()
......
......@@ -2,7 +2,8 @@ from nose.tools import eq_, ok_
import peewee
from flask.ext import wtf
from wtforms import fields
from flask.ext.admin.contrib.peeweemodel import ModelView
from . import setup
......@@ -73,10 +74,10 @@ def test_model():
eq_(view._filters, None)
# Verify form
eq_(view._create_form_class.test1.field_class, wtf.TextField)
eq_(view._create_form_class.test2.field_class, wtf.TextField)
eq_(view._create_form_class.test3.field_class, wtf.TextAreaField)
eq_(view._create_form_class.test4.field_class, wtf.TextAreaField)
eq_(view._create_form_class.test1.field_class, fields.TextField)
eq_(view._create_form_class.test2.field_class, fields.TextField)
eq_(view._create_form_class.test3.field_class, fields.TextAreaField)
eq_(view._create_form_class.test4.field_class, fields.TextAreaField)
# Make some test clients
client = app.test_client()
......
from nose.tools import eq_, ok_, raises
from flask.ext import wtf
from wtforms import fields
from flask.ext.admin.contrib.sqlamodel import ModelView
from . import setup
......@@ -439,12 +439,12 @@ def test_form_override():
db.create_all()
view1 = CustomModelView(Model, db.session, endpoint='view1')
view2 = CustomModelView(Model, db.session, endpoint='view2', form_overrides=dict(test=wtf.FileField))
view2 = CustomModelView(Model, db.session, endpoint='view2', form_overrides=dict(test=fields.FileField))
admin.add_view(view1)
admin.add_view(view2)
eq_(view1._create_form_class.test.field_class, wtf.TextField)
eq_(view2._create_form_class.test.field_class, wtf.FileField)
eq_(view1._create_form_class.test.field_class, fields.TextField)
eq_(view2._create_form_class.test.field_class, fields.FileField)
def test_relations():
......@@ -499,7 +499,7 @@ def test_multiple_delete():
client = app.test_client()
rv = client.post('/admin/model1view/action/', data=dict(action='delete', rowid=[1,2,3]))
rv = client.post('/admin/model1view/action/', data=dict(action='delete', rowid=[1, 2, 3]))
eq_(rv.status_code, 302)
eq_(M1.query.count(), 0)
......
# -*- coding: utf-8 -*-
from nose.tools import eq_, ok_, raises
from flask.ext import wtf
from flask.ext.admin.contrib.sqlamodel import ModelView, fields
from wtforms import fields
from flask.ext.admin.contrib.sqlamodel import ModelView
from flask.ext.admin.contrib.sqlamodel.fields import InlineModelFormList
from . import setup
......@@ -42,8 +44,8 @@ def test_inline_form():
eq_(view.endpoint, 'userview')
# Verify form
eq_(view._create_form_class.name.field_class, wtf.TextField)
eq_(view._create_form_class.info.field_class, fields.InlineModelFormList)
eq_(view._create_form_class.name.field_class, fields.TextField)
eq_(view._create_form_class.info.field_class, InlineModelFormList)
rv = client.get('/admin/userview/')
eq_(rv.status_code, 200)
......
from nose.tools import eq_, ok_, raises
from nose.tools import eq_, ok_
from flask import Flask
from flask.helpers import get_flashed_messages
from flask.ext.admin import Admin
from flask.ext.admin.model import base, filters
from wtforms import fields
from flask.ext import wtf
from flask.ext.admin import Admin, form
from flask.ext.admin.model import base, filters
class Model(object):
......@@ -17,10 +16,10 @@ class Model(object):
self.col3 = c3
class Form(wtf.Form):
col1 = wtf.TextField()
col2 = wtf.TextField()
col3 = wtf.TextField()
class Form(form.BaseForm):
col1 = fields.TextField()
col2 = fields.TextField()
col3 = fields.TextField()
class SimpleFilter(filters.BaseFilter):
......@@ -298,7 +297,7 @@ def test_form():
def test_custom_form():
app, admin = setup()
class TestForm(wtf.Form):
class TestForm(form.BaseForm):
pass
view = MockModelView(Model, form=TestForm)
......
......@@ -43,8 +43,7 @@ setup(
platforms='any',
install_requires=[
'six>=1.2',
'Flask>=0.7',
'Flask-WTF>=0.6',
'Flask>=0.7'
],
tests_require=[
'nose>=1.0'
......
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