Commit 53c68c72 authored by Serge S. Koval's avatar Serge S. Koval

Python 3 fixes.

parent f6894398
...@@ -26,7 +26,7 @@ class User(db.Model): ...@@ -26,7 +26,7 @@ class User(db.Model):
email = db.Column(db.String(120), unique=True) email = db.Column(db.String(120), unique=True)
# Required for administrative interface # Required for administrative interface
def __unicode__(self): def __str__(self):
return self.username return self.username
...@@ -48,7 +48,7 @@ class Post(db.Model): ...@@ -48,7 +48,7 @@ class Post(db.Model):
tags = db.relationship('Tag', secondary=post_tags_table) tags = db.relationship('Tag', secondary=post_tags_table)
def __unicode__(self): def __str__(self):
return self.title return self.title
...@@ -56,7 +56,7 @@ class Tag(db.Model): ...@@ -56,7 +56,7 @@ class Tag(db.Model):
id = db.Column(db.Integer, primary_key=True) id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.Unicode(64)) name = db.Column(db.Unicode(64))
def __unicode__(self): def __str__(self):
return self.name return self.name
...@@ -69,7 +69,7 @@ class UserInfo(db.Model): ...@@ -69,7 +69,7 @@ class UserInfo(db.Model):
user_id = db.Column(db.Integer(), db.ForeignKey(User.id)) user_id = db.Column(db.Integer(), db.ForeignKey(User.id))
user = db.relationship(User, backref='info') user = db.relationship(User, backref='info')
def __unicode__(self): def __str__(self):
return '%s - %s' % (self.key, self.value) return '%s - %s' % (self.key, self.value)
...@@ -79,7 +79,7 @@ class Tree(db.Model): ...@@ -79,7 +79,7 @@ class Tree(db.Model):
parent_id = db.Column(db.Integer, db.ForeignKey('tree.id')) parent_id = db.Column(db.Integer, db.ForeignKey('tree.id'))
parent = db.relationship('Tree', remote_side=[id], backref='children') parent = db.relationship('Tree', remote_side=[id], backref='children')
def __unicode__(self): def __str__(self):
return self.name return self.name
......
# -*- coding: utf-8 -*-
"""
flask.ext.admin._compat
~~~~~~~~~~~~~~~~~~~~~~~
Some py2/py3 compatibility support based on a stripped down
version of six so we don't have to depend on a specific version
of it.
:copyright: (c) 2013 by Armin Ronacher.
:license: BSD, see LICENSE for more details.
"""
import sys
PY2 = sys.version_info[0] == 2
if not PY2:
text_type = str
string_types = (str,)
integer_types = (int, )
iterkeys = lambda d: iter(d.keys())
itervalues = lambda d: iter(d.values())
iteritems = lambda d: iter(d.items())
def as_unicode(text):
return str(text)
from functools import reduce
else:
unicode_type = unicode
text_type = unicode
string_types = (str, unicode)
integer_types = (int, long)
iterkeys = lambda d: d.iterkeys()
itervalues = lambda d: d.itervalues()
iteritems = lambda d: d.iteritems()
def as_unicode(text):
return unicode(text)
reduce = __builtin__.reduce
def with_metaclass(meta, *bases):
# This requires a bit of explanation: the basic idea is to make a
# dummy metaclass for one level of class instantiation that replaces
# itself with the actual metaclass. Because of internal type checks
# we also need to make sure that we downgrade the custom metaclass
# for one level to something closer to type (that's why __call__ and
# __init__ comes back from type etc.).
#
# This has the advantage over six.with_metaclass in that it does not
# introduce dummy classes into the final MRO.
class metaclass(meta):
__call__ = type.__call__
__init__ = type.__init__
def __new__(cls, name, this_bases, d):
if this_bases is None:
return type.__new__(cls, name, (), d)
return meta(name, bases, d)
return metaclass('temporary_class', None, {})
from flask import request, url_for, redirect from flask import request, url_for, redirect
from flask.ext.admin.tools import get_dict_attr from flask.ext.admin import tools, _compat
def action(name, text, confirmation=None): def action(name, text, confirmation=None):
...@@ -53,7 +53,7 @@ class ActionsMixin(object): ...@@ -53,7 +53,7 @@ class ActionsMixin(object):
self._actions_data = {} self._actions_data = {}
for p in dir(self): for p in dir(self):
attr = get_dict_attr(self, p) attr = tools.get_dict_attr(self, p)
if hasattr(attr, '_action'): if hasattr(attr, '_action'):
name, text, desc = attr._action name, text, desc = attr._action
...@@ -85,12 +85,12 @@ class ActionsMixin(object): ...@@ -85,12 +85,12 @@ class ActionsMixin(object):
name, text = act name, text = act
if self.is_action_allowed(name): if self.is_action_allowed(name):
text = unicode(text) text = _compat.as_unicode(text)
actions.append((name, text)) actions.append((name, text))
confirmation = self._actions_data[name][2] confirmation = self._actions_data[name][2]
if confirmation: if confirmation:
actions_confirmation[name] = unicode(confirmation) actions_confirmation[name] = _compat.text_type(confirmation)
return actions, actions_confirmation return actions, actions_confirmation
......
from functools import wraps from functools import wraps
from re import sub from re import sub
import six
from flask import Blueprint, render_template, url_for, abort, g from flask import Blueprint, render_template, url_for, abort, g
from flask.ext.admin import babel from flask.ext.admin import babel, _compat
from flask.ext.admin import helpers as h from flask.ext.admin import helpers as h
...@@ -95,7 +94,7 @@ class BaseMeta(object): ...@@ -95,7 +94,7 @@ class BaseMeta(object):
pass pass
class BaseView(six.with_metaclass(AdminViewMeta, BaseMeta)): class BaseView(_compat.with_metaclass(AdminViewMeta, BaseMeta)):
""" """
Base administrative view. Base administrative view.
......
...@@ -4,6 +4,7 @@ from flask import flash ...@@ -4,6 +4,7 @@ from flask import flash
from flask.ext.admin.babel import gettext, ngettext, lazy_gettext from flask.ext.admin.babel import gettext, ngettext, lazy_gettext
from flask.ext.admin.model import BaseModelView from flask.ext.admin.model import BaseModelView
from flask.ext.admin import _compat
import mongoengine import mongoengine
from bson.objectid import ObjectId from bson.objectid import ObjectId
...@@ -115,7 +116,7 @@ class ModelView(BaseModelView): ...@@ -115,7 +116,7 @@ class ModelView(BaseModelView):
if model is None: if model is None:
model = self.model model = self.model
return sorted(model._fields.iteritems(), key=lambda n: n[1].creation_counter) return sorted(_compat.iteritems(model._fields), key=lambda n: n[1].creation_counter)
def scaffold_pk(self): def scaffold_pk(self):
# MongoEngine models have predefined 'id' as a key # MongoEngine models have predefined 'id' as a key
...@@ -171,7 +172,7 @@ class ModelView(BaseModelView): ...@@ -171,7 +172,7 @@ class ModelView(BaseModelView):
""" """
if self.column_searchable_list: if self.column_searchable_list:
for p in self.column_searchable_list: for p in self.column_searchable_list:
if isinstance(p, basestring): if isinstance(p, _compat.string_types):
p = self.model._fields.get(p) p = self.model._fields.get(p)
if p is None: if p is None:
...@@ -195,7 +196,7 @@ class ModelView(BaseModelView): ...@@ -195,7 +196,7 @@ class ModelView(BaseModelView):
:param name: :param name:
Either field name or field instance Either field name or field instance
""" """
if isinstance(name, basestring): if isinstance(name, _compat.string_types):
attr = self.model._fields.get(name) attr = self.model._fields.get(name)
else: else:
attr = name attr = name
...@@ -206,7 +207,7 @@ class ModelView(BaseModelView): ...@@ -206,7 +207,7 @@ class ModelView(BaseModelView):
# Find name # Find name
visible_name = None visible_name = None
if not isinstance(name, basestring): if not isinstance(name, _compat.string_types):
visible_name = self.get_column_name(attr.name) visible_name = self.get_column_name(attr.name)
if not visible_name: if not visible_name:
......
...@@ -5,7 +5,7 @@ from peewee import (DateTimeField, DateField, TimeField, ...@@ -5,7 +5,7 @@ from peewee import (DateTimeField, DateField, TimeField,
from wtfpeewee.orm import ModelConverter, model_form from wtfpeewee.orm import ModelConverter, model_form
from flask.ext.admin import form from flask.ext.admin import form, _compat
from flask.ext.admin.model.form import InlineFormAdmin, InlineModelConverterBase from flask.ext.admin.model.form import InlineFormAdmin, InlineModelConverterBase
from flask.ext.admin.model.fields import InlineModelFormField, InlineFieldList from flask.ext.admin.model.fields import InlineModelFormField, InlineFieldList
...@@ -164,6 +164,6 @@ class InlineModelConverter(InlineModelConverterBase): ...@@ -164,6 +164,6 @@ class InlineModelConverter(InlineModelConverterBase):
def save_inline(form, model): def save_inline(form, model):
for _, f in form._fields.iteritems(): for _, f in _compat(form._fields):
if f.type == 'InlineModelFormList': if f.type == 'InlineModelFormList':
f.save_related(model) f.save_related(model)
...@@ -2,7 +2,7 @@ import logging ...@@ -2,7 +2,7 @@ import logging
from flask import flash from flask import flash
from flask.ext.admin import form from flask.ext.admin import form, _compat
from flask.ext.admin.babel import gettext, ngettext, lazy_gettext from flask.ext.admin.babel import gettext, ngettext, lazy_gettext
from flask.ext.admin.model import BaseModelView from flask.ext.admin.model import BaseModelView
...@@ -173,7 +173,7 @@ class ModelView(BaseModelView): ...@@ -173,7 +173,7 @@ class ModelView(BaseModelView):
def init_search(self): def init_search(self):
if self.column_searchable_list: if self.column_searchable_list:
for p in self.column_searchable_list: for p in self.column_searchable_list:
if isinstance(p, basestring): if isinstance(p, _compat.string_types):
p = getattr(self.model, p) p = getattr(self.model, p)
field_type = type(p) field_type = type(p)
...@@ -189,7 +189,7 @@ class ModelView(BaseModelView): ...@@ -189,7 +189,7 @@ class ModelView(BaseModelView):
return bool(self._search_fields) return bool(self._search_fields)
def scaffold_filters(self, name): def scaffold_filters(self, name):
if isinstance(name, basestring): if isinstance(name, _compat.string_types):
attr = getattr(self.model, name, None) attr = getattr(self.model, name, None)
else: else:
attr = name attr = name
...@@ -202,7 +202,7 @@ class ModelView(BaseModelView): ...@@ -202,7 +202,7 @@ class ModelView(BaseModelView):
visible_name = '%s / %s' % (self.get_column_name(attr.model_class.__name__), visible_name = '%s / %s' % (self.get_column_name(attr.model_class.__name__),
self.get_column_name(attr.name)) self.get_column_name(attr.name))
else: else:
if not isinstance(name, basestring): if not isinstance(name, _compat.string_types):
visible_name = self.get_column_name(attr.name) visible_name = self.get_column_name(attr.name)
else: else:
visible_name = self.get_column_name(name) visible_name = self.get_column_name(name)
...@@ -253,7 +253,7 @@ class ModelView(BaseModelView): ...@@ -253,7 +253,7 @@ class ModelView(BaseModelView):
return query return query
def _order_by(self, query, joins, sort_field, sort_desc): def _order_by(self, query, joins, sort_field, sort_desc):
if isinstance(sort_field, basestring): if isinstance(sort_field, _compat.string_types):
field = getattr(self.model, sort_field) field = getattr(self.model, sort_field)
query = query.order_by(field.desc() if sort_desc else field.asc()) query = query.order_by(field.desc() if sort_desc else field.asc())
elif isinstance(sort_field, Field): elif isinstance(sort_field, Field):
......
...@@ -5,8 +5,8 @@ from bson import ObjectId ...@@ -5,8 +5,8 @@ from bson import ObjectId
from bson.errors import InvalidId from bson.errors import InvalidId
from flask import flash from flask import flash
from jinja2 import contextfunction
from flask.ext.admin import _compat
from flask.ext.admin.babel import gettext, ngettext, lazy_gettext from flask.ext.admin.babel import gettext, ngettext, lazy_gettext
from flask.ext.admin.model import BaseModelView from flask.ext.admin.model import BaseModelView
from flask.ext.admin.actions import action from flask.ext.admin.actions import action
...@@ -92,7 +92,7 @@ class ModelView(BaseModelView): ...@@ -92,7 +92,7 @@ class ModelView(BaseModelView):
""" """
if self.column_searchable_list: if self.column_searchable_list:
for p in self.column_searchable_list: for p in self.column_searchable_list:
if not isinstance(p, basestring): if not isinstance(p, _compat.string_types):
raise ValueError('Expected string') raise ValueError('Expected string')
# TODO: Validation? # TODO: Validation?
......
...@@ -8,6 +8,7 @@ from wtforms.fields import SelectFieldBase ...@@ -8,6 +8,7 @@ from wtforms.fields import SelectFieldBase
from wtforms.validators import ValidationError from wtforms.validators import ValidationError
from .tools import get_primary_key from .tools import get_primary_key
from flask.ext.admin import _compat
from flask.ext.admin.model.fields import InlineFieldList, InlineModelFormField from flask.ext.admin.model.fields import InlineFieldList, InlineModelFormField
...@@ -63,14 +64,14 @@ class QuerySelectField(SelectFieldBase): ...@@ -63,14 +64,14 @@ class QuerySelectField(SelectFieldBase):
if get_pk is None: if get_pk is None:
if not has_identity_key: if not has_identity_key:
raise Exception('The sqlalchemy identity_key function could not be imported.') raise Exception(u'The sqlalchemy identity_key function could not be imported.')
self.get_pk = get_pk_from_identity self.get_pk = get_pk_from_identity
else: else:
self.get_pk = get_pk self.get_pk = get_pk
if get_label is None: if get_label is None:
self.get_label = lambda x: x self.get_label = lambda x: x
elif isinstance(get_label, basestring): elif isinstance(get_label, _compat.string_types):
self.get_label = operator.attrgetter(get_label) self.get_label = operator.attrgetter(get_label)
else: else:
self.get_label = get_label self.get_label = get_label
...@@ -98,7 +99,7 @@ class QuerySelectField(SelectFieldBase): ...@@ -98,7 +99,7 @@ class QuerySelectField(SelectFieldBase):
if self._object_list is None: if self._object_list is None:
query = self.query or self.query_factory() query = self.query or self.query_factory()
get_pk = self.get_pk get_pk = self.get_pk
self._object_list = list((unicode(get_pk(obj)), obj) for obj in query) self._object_list = [(_compat.as_unicode(get_pk(obj)), obj) for obj in query]
return self._object_list return self._object_list
def iter_choices(self): def iter_choices(self):
...@@ -177,7 +178,7 @@ class QuerySelectMultipleField(QuerySelectField): ...@@ -177,7 +178,7 @@ class QuerySelectMultipleField(QuerySelectField):
obj_list = list(x[1] for x in self._get_object_list()) obj_list = list(x[1] for x in self._get_object_list())
for v in self.data: for v in self.data:
if v not in obj_list: if v not in obj_list:
raise ValidationError(self.gettext('Not a valid choice')) raise ValidationError(self.gettext(u'Not a valid choice'))
class InlineModelFormList(InlineFieldList): class InlineModelFormList(InlineFieldList):
...@@ -238,4 +239,4 @@ class InlineModelFormList(InlineFieldList): ...@@ -238,4 +239,4 @@ class InlineModelFormList(InlineFieldList):
def get_pk_from_identity(obj): def get_pk_from_identity(obj):
# TODO: Remove me # TODO: Remove me
cls, key = identity_key(instance=obj) cls, key = identity_key(instance=obj)
return u':'.join(unicode(x) for x in key) return u':'.join(_compat.as_unicode(x) for x in key)
...@@ -26,7 +26,8 @@ class Unique(object): ...@@ -26,7 +26,8 @@ class Unique(object):
def __call__(self, form, field): def __call__(self, form, field):
try: try:
obj = (self.db_session.query(self.model) obj = (self.db_session.query(self.model)
.filter(self.column == field.data).one()) .filter(self.column == field.data)
.one())
if not hasattr(form, '_obj') or not form._obj == obj: if not hasattr(form, '_obj') or not form._obj == obj:
if self.message is None: if self.message is None:
......
...@@ -7,6 +7,7 @@ from sqlalchemy import or_, Column, func ...@@ -7,6 +7,7 @@ from sqlalchemy import or_, Column, func
from flask import flash from flask import flash
from flask.ext.admin import _compat
from flask.ext.admin.tools import ObsoleteAttr from flask.ext.admin.tools import ObsoleteAttr
from flask.ext.admin.babel import gettext, ngettext, lazy_gettext from flask.ext.admin.babel import gettext, ngettext, lazy_gettext
from flask.ext.admin.model import BaseModelView from flask.ext.admin.model import BaseModelView
...@@ -348,7 +349,7 @@ class ModelView(BaseModelView): ...@@ -348,7 +349,7 @@ class ModelView(BaseModelView):
return columns return columns
def _get_columns_for_field(self, field): def _get_columns_for_field(self, field):
if isinstance(field, basestring): if isinstance(field, _compat.string_types):
attr = getattr(self.model, field, None) attr = getattr(self.model, field, None)
if field is None: if field is None:
...@@ -410,7 +411,7 @@ class ModelView(BaseModelView): ...@@ -410,7 +411,7 @@ class ModelView(BaseModelView):
""" """
join_tables = [] join_tables = []
if isinstance(name, basestring): if isinstance(name, _compat.string_types):
model = self.model model = self.model
for attribute in name.split('.'): for attribute in name.split('.'):
...@@ -474,7 +475,7 @@ class ModelView(BaseModelView): ...@@ -474,7 +475,7 @@ class ModelView(BaseModelView):
self.get_column_name(column.name) self.get_column_name(column.name)
) )
else: else:
if not isinstance(name, basestring): if not isinstance(name, _compat.string_types):
visible_name = self.get_column_name(name.property.key) visible_name = self.get_column_name(name.property.key)
else: else:
visible_name = self.get_column_name(name) visible_name = self.get_column_name(name)
...@@ -596,7 +597,7 @@ class ModelView(BaseModelView): ...@@ -596,7 +597,7 @@ class ModelView(BaseModelView):
""" """
# TODO: Preprocessing for joins # TODO: Preprocessing for joins
# Try to handle it as a string # Try to handle it as a string
if isinstance(sort_field, basestring): if isinstance(sort_field, _compat.string_types):
# Create automatic join against a table if column name # Create automatic join against a table if column name
# contains dot. # contains dot.
if '.' in sort_field: if '.' in sort_field:
...@@ -637,7 +638,7 @@ class ModelView(BaseModelView): ...@@ -637,7 +638,7 @@ class ModelView(BaseModelView):
if order is not None: if order is not None:
field, direction = order field, direction = order
if isinstance(field, basestring): if isinstance(field, _compat.string_types):
field = getattr(self.model, field) field = getattr(self.model, field)
return field, direction return field, direction
...@@ -764,7 +765,7 @@ class ModelView(BaseModelView): ...@@ -764,7 +765,7 @@ class ModelView(BaseModelView):
self.session.add(model) self.session.add(model)
self.on_model_change(form, model) self.on_model_change(form, model)
self.session.commit() self.session.commit()
except Exception, ex: except Exception as ex:
flash(gettext('Failed to create model. %(error)s', error=str(ex)), 'error') flash(gettext('Failed to create model. %(error)s', error=str(ex)), 'error')
logging.exception('Failed to create model') logging.exception('Failed to create model')
self.session.rollback() self.session.rollback()
...@@ -787,7 +788,7 @@ class ModelView(BaseModelView): ...@@ -787,7 +788,7 @@ class ModelView(BaseModelView):
form.populate_obj(model) form.populate_obj(model)
self.on_model_change(form, model) self.on_model_change(form, model)
self.session.commit() self.session.commit()
except Exception, ex: except Exception as ex:
flash(gettext('Failed to update model. %(error)s', error=str(ex)), 'error') flash(gettext('Failed to update model. %(error)s', error=str(ex)), 'error')
logging.exception('Failed to update model') logging.exception('Failed to update model')
self.session.rollback() self.session.rollback()
...@@ -810,7 +811,7 @@ class ModelView(BaseModelView): ...@@ -810,7 +811,7 @@ class ModelView(BaseModelView):
self.session.delete(model) self.session.delete(model)
self.session.commit() self.session.commit()
return True return True
except Exception, ex: except Exception as ex:
flash(gettext('Failed to delete model. %(error)s', error=str(ex)), 'error') flash(gettext('Failed to delete model. %(error)s', error=str(ex)), 'error')
logging.exception('Failed to delete model') logging.exception('Failed to delete model')
self.session.rollback() self.session.rollback()
...@@ -848,5 +849,5 @@ class ModelView(BaseModelView): ...@@ -848,5 +849,5 @@ class ModelView(BaseModelView):
'%(count)s models were successfully deleted.', '%(count)s models were successfully deleted.',
count, count,
count=count)) count=count))
except Exception, ex: except Exception as ex:
flash(gettext('Failed to delete models. %(error)s', error=str(ex)), 'error') flash(gettext('Failed to delete models. %(error)s', error=str(ex)), 'error')
...@@ -5,11 +5,15 @@ from wtforms import form, fields, widgets ...@@ -5,11 +5,15 @@ from wtforms import form, fields, widgets
from flask.globals import _request_ctx_stack from flask.globals import _request_ctx_stack
from flask.ext.admin.babel import gettext, ngettext from flask.ext.admin.babel import gettext, ngettext
from flask.ext.admin import helpers as h from flask.ext.admin import helpers as h
from flask.ext.admin import _compat
# TODO: Use flask.ext.wtf if possible # TODO: Use flask.ext.wtf if possible
class BaseForm(form.Form): class BaseForm(form.Form):
pass def __init__(self, formdata=None, obj=None, prefix=u'', **kwargs):
self._obj = obj
super(BaseForm, self).__init__(formdata=formdata, obj=obj, prefix=prefix, **kwargs)
class TimeField(fields.Field): class TimeField(fields.Field):
...@@ -88,7 +92,7 @@ class Select2Field(fields.SelectField): ...@@ -88,7 +92,7 @@ class Select2Field(fields.SelectField):
""" """
widget = Select2Widget() widget = Select2Widget()
def __init__(self, label=None, validators=None, coerce=unicode, def __init__(self, label=None, validators=None, coerce=_compat.text_type,
choices=None, allow_blank=False, blank_text=None, **kwargs): choices=None, allow_blank=False, blank_text=None, **kwargs):
super(Select2Field, self).__init__( super(Select2Field, self).__init__(
label, validators, coerce, choices, **kwargs label, validators, coerce, choices, **kwargs
......
...@@ -10,7 +10,7 @@ from flask.ext.admin.base import BaseView, expose ...@@ -10,7 +10,7 @@ from flask.ext.admin.base import BaseView, expose
from flask.ext.admin.tools import rec_getattr, ObsoleteAttr from flask.ext.admin.tools import rec_getattr, ObsoleteAttr
from flask.ext.admin.model import filters, typefmt from flask.ext.admin.model import filters, typefmt
from flask.ext.admin.actions import ActionsMixin from flask.ext.admin.actions import ActionsMixin
from flask.ext.admin import get_form_data, validate_form_on_submit from flask.ext.admin.helpers import get_form_data, validate_form_on_submit
class BaseModelView(BaseView, ActionsMixin): class BaseModelView(BaseView, ActionsMixin):
...@@ -937,7 +937,7 @@ class BaseModelView(BaseView, ActionsMixin): ...@@ -937,7 +937,7 @@ class BaseModelView(BaseView, ActionsMixin):
search, filters) search, filters)
# Calculate number of pages # Calculate number of pages
num_pages = count / self.page_size num_pages = count // self.page_size
if count % self.page_size != 0: if count % self.page_size != 0:
num_pages += 1 num_pages += 1
...@@ -1014,8 +1014,7 @@ class BaseModelView(BaseView, ActionsMixin): ...@@ -1014,8 +1014,7 @@ class BaseModelView(BaseView, ActionsMixin):
# Actions # Actions
actions=actions, actions=actions,
actions_confirmation=actions_confirmation actions_confirmation=actions_confirmation)
)
@expose('/new/', methods=('GET', 'POST')) @expose('/new/', methods=('GET', 'POST'))
def create_view(self): def create_view(self):
......
...@@ -2,6 +2,7 @@ import itertools ...@@ -2,6 +2,7 @@ import itertools
from wtforms.fields import FieldList, FormField from wtforms.fields import FieldList, FormField
from flask.ext.admin import _compat
from .widgets import InlineFieldListWidget, InlineFormWidget from .widgets import InlineFieldListWidget, InlineFormWidget
...@@ -22,9 +23,9 @@ class InlineFieldList(FieldList): ...@@ -22,9 +23,9 @@ class InlineFieldList(FieldList):
def __call__(self, **kwargs): def __call__(self, **kwargs):
return self.widget(self, return self.widget(self,
template=self.template, template=self.template,
check=self.display_row_controls, check=self.display_row_controls,
**kwargs) **kwargs)
def display_row_controls(self, field): def display_row_controls(self, field):
return True return True
...@@ -82,7 +83,7 @@ class InlineModelFormField(FormField): ...@@ -82,7 +83,7 @@ class InlineModelFormField(FormField):
return getattr(self.form, self._pk).data return getattr(self.form, self._pk).data
def populate_obj(self, obj, name): def populate_obj(self, obj, name):
for name, field in self.form._fields.iteritems(): for name, field in _compat.iteritems(self.form._fields):
if name != self._pk: if name != self._pk:
field.populate_obj(obj, name) field.populate_obj(obj, name)
......
from flask.ext.admin import _compat
from flask.ext.admin.babel import lazy_gettext from flask.ext.admin.babel import lazy_gettext
...@@ -30,7 +31,7 @@ class BaseFilter(object): ...@@ -30,7 +31,7 @@ class BaseFilter(object):
Associated administrative view class. Associated administrative view class.
""" """
if self.options: if self.options:
return [(v, unicode(n)) for v, n in self.options] return [(v, _compat.as_unicode(n)) for v, n in self.options]
return None return None
......
import inspect import inspect
from flask.ext.admin.form import BaseForm from flask.ext.admin.form import BaseForm
from flask.ext.admin import _compat
def converts(*args): def converts(*args):
...@@ -37,7 +38,7 @@ class InlineFormAdmin(object): ...@@ -37,7 +38,7 @@ class InlineFormAdmin(object):
if not hasattr(self, k): if not hasattr(self, k):
setattr(self, k, None) setattr(self, k, None)
for k, v in kwargs.iteritems(): for k, v in _compat.iteritems(kwargs):
setattr(self, k, v) setattr(self, k, v)
def postprocess_form(self, form_class): def postprocess_form(self, form_class):
......
from jinja2 import Markup from jinja2 import Markup
from flask.ext.admin import _compat
def null_formatter(view, value): def null_formatter(view, value):
...@@ -38,7 +39,7 @@ def list_formatter(view, values): ...@@ -38,7 +39,7 @@ def list_formatter(view, values):
:param values: :param values:
Value to check Value to check
""" """
return u', '.join(unicode(v) for v in values) return u', '.join(_compat.as_unicode(v) for v in values)
BASE_FORMATTERS = { BASE_FORMATTERS = {
......
...@@ -22,7 +22,7 @@ ...@@ -22,7 +22,7 @@
this.addInlineField = function(id, el, template) { this.addInlineField = function(id, el, template) {
var $el = $(el); var $el = $(el);
var $template = $(template); var $template = $($(template).html());
// Figure out new field ID // Figure out new field ID
var lastField = $el.children('.fa-inline-field').last(); var lastField = $el.children('.fa-inline-field').last();
...@@ -30,7 +30,7 @@ ...@@ -30,7 +30,7 @@
var prefix = id + '-0'; var prefix = id + '-0';
if (lastField.length > 0) { if (lastField.length > 0) {
var parts = $(lastField[0]).attr('id').split('-'); var parts = $(lastField[0]).attr('id').split('-');
idx = parseInt(parts[parts.length - 1]) + 1; idx = parseInt(parts[parts.length - 1], 10) + 1;
prefix = id + '-' + idx; prefix = id + '-' + idx;
} }
......
{% macro render_template(template, render) -%}
<div class="fa-inline-field">
<div class="fa-inline-field-control">
<a href="javascript:void(0)" class="fa-remove-field"><i class="icon-remove"></i></a>
</div>
{{ render(template) }}
</div>
{%- endmacro %}
{% macro render_inline_fields(field, template, render, check=None) %} {% macro render_inline_fields(field, template, render, check=None) %}
<div class="well"> <div class="well">
<div id="{{ field.id }}-fields"> <div id="{{ field.id }}-fields">
...@@ -23,6 +14,14 @@ ...@@ -23,6 +14,14 @@
</div> </div>
{% endfor %} {% endfor %}
</div> </div>
<a href="javascript:void(0)" class="btn" onclick="faForm.addInlineField('{{ field.id }}', '#{{ field.id }}-fields', {{ render_template(template, render)|tojson }});">{{ _gettext('Add') }} {{ field.label.text }}</a> <div id="{{ field.id }}-template" class="hide">
<div class="fa-inline-field">
<div class="fa-inline-field-control">
<a href="javascript:void(0)" class="fa-remove-field"><i class="icon-remove"></i></a>
</div>
{{ render(template) }}
</div>
</div>
<a id="{{ field.id }}-button" href="javascript:void(0)" class="btn" onclick="faForm.addInlineField('{{ field.id }}', '#{{ field.id }}-fields', '#{{ field.id }}-template');">{{ _gettext('Add') }} {{ field.label.text }}</a>
</div> </div>
{% endmacro %} {% endmacro %}
...@@ -4,6 +4,7 @@ import peewee ...@@ -4,6 +4,7 @@ import peewee
from wtforms import fields from wtforms import fields
from flask.ext.admin import _compat
from flask.ext.admin.contrib.peeweemodel import ModelView from flask.ext.admin.contrib.peeweemodel import ModelView
from . import setup from . import setup
...@@ -13,7 +14,7 @@ class CustomModelView(ModelView): ...@@ -13,7 +14,7 @@ class CustomModelView(ModelView):
def __init__(self, model, def __init__(self, model,
name=None, category=None, endpoint=None, url=None, name=None, category=None, endpoint=None, url=None,
**kwargs): **kwargs):
for k, v in kwargs.iteritems(): for k, v in _compat.iteritems(kwargs):
setattr(self, k, v) setattr(self, k, v)
super(CustomModelView, self).__init__(model, super(CustomModelView, self).__init__(model,
......
from nose.tools import eq_, ok_, raises from nose.tools import eq_, ok_, raises
from wtforms import fields from wtforms import fields
from flask.ext.admin import _compat
from flask.ext.admin.contrib.sqlamodel import ModelView from flask.ext.admin.contrib.sqlamodel import ModelView
from . import setup from . import setup
...@@ -10,7 +12,7 @@ class CustomModelView(ModelView): ...@@ -10,7 +12,7 @@ class CustomModelView(ModelView):
def __init__(self, model, session, def __init__(self, model, session,
name=None, category=None, endpoint=None, url=None, name=None, category=None, endpoint=None, url=None,
**kwargs): **kwargs):
for k, v in kwargs.iteritems(): for k, v in _compat.iteritems(kwargs):
setattr(self, k, v) setattr(self, k, v)
super(CustomModelView, self).__init__(model, session, super(CustomModelView, self).__init__(model, session,
......
...@@ -4,7 +4,7 @@ from flask import Flask ...@@ -4,7 +4,7 @@ from flask import Flask
from wtforms import fields from wtforms import fields
from flask.ext.admin import Admin, form from flask.ext.admin import Admin, form, _compat
from flask.ext.admin.model import base, filters from flask.ext.admin.model import base, filters
...@@ -35,7 +35,7 @@ class MockModelView(base.BaseModelView): ...@@ -35,7 +35,7 @@ class MockModelView(base.BaseModelView):
def __init__(self, model, name=None, category=None, endpoint=None, url=None, def __init__(self, model, name=None, category=None, endpoint=None, url=None,
**kwargs): **kwargs):
# Allow to set any attributes from parameters # Allow to set any attributes from parameters
for k, v in kwargs.iteritems(): for k, v in _compat.iteritems(kwargs):
setattr(self, k, v) setattr(self, k, v)
super(MockModelView, self).__init__(model, name, category, endpoint, url) super(MockModelView, self).__init__(model, name, category, endpoint, url)
......
...@@ -2,6 +2,9 @@ import sys ...@@ -2,6 +2,9 @@ import sys
import warnings import warnings
import traceback import traceback
# Python 3 compatibility
from ._compat import reduce
def import_module(name, required=True): def import_module(name, required=True):
""" """
......
...@@ -42,7 +42,6 @@ setup( ...@@ -42,7 +42,6 @@ setup(
zip_safe=False, zip_safe=False,
platforms='any', platforms='any',
install_requires=[ install_requires=[
'six>=1.2',
'Flask>=0.7' 'Flask>=0.7'
], ],
tests_require=[ tests_require=[
......
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