2014-02-01 2 views
1

Я создал приложение Flask с бэкэндом SQLAlchemy, который был действительно прямым. Тем не менее, я столкнулся с проблемой при использовании расширения Admin. В то время как это работает хорошо для большинства моделей, некоторые из них дают мне следующую ошибку:Ошибка флага/SQLAlchemy Unicode Error

TypeError: 'unicode' object is not callable 

Вот пример одной из проблемных моделей:

class Trade(db.Model): 

    __tablename__ = 'trade' 

    id = db.Column(db.Integer, primary_key=True) 

    issuer_id = db.Column(db.Integer, 
          db.ForeignKey('issuer.id'), primary_key=True) 

    obligation_id = db.Column(db.Integer, 
           db.ForeignKey('obligation.id')) 

    obligation = db.relationship('Obligation', backref='trades') 

    type = db.Column(db.String(50)) 
    purpose = db.Column(db.String(50)) 

    date = db.Column(db.Date) 
    currency = db.Column(db.Text) 
    amount = db.Column(db.Float) 

    __mapper_args__ = { 
     'polymorphic_on': purpose, 
     'polymorphic_identity': 'trade', 
     'with_polymorphic': '*' 
    } 

    def __str__(self): 
     return self.obligation + ' ' + self.date.strftime('%y-%m-%d') 

Чтобы дать некоторый контекст, каким это вызвано расширением, у меня есть код, который создает страницы администрирования для всех моих моделей sqlalchemy.

from test_app import app 
from flask.ext.admin import Admin 
from test_app.db import db, get_model, models_list 

from flask.ext.admin.contrib import sqla 

admin = Admin(app, name='Test App') 

for model in sorted(models_list()): 

    admin_cls = type(model, (sqla.ModelView,), {'column_display_pk': False}) 
    admin_view = admin_cls(get_model(model), db.session) 
    admin.add_view(admin_view) 

Конечный результат является то, что, когда я перейти на страницу администратора для этой модели я получаю следующую ошибку, которая не дает много контекста относительно того, что строка коды вызывает проблему.

File "/home/user/app/venv/lib/python2.7/site-packages/flask/app.py", line 1836, in __call__ 
return self.wsgi_app(environ, start_response) 
File "/home/user/app/venv/lib/python2.7/site-packages/flask/app.py", line 1820, in wsgi_app 
response = self.make_response(self.handle_exception(e)) 
File "/home/user/app/venv/lib/python2.7/site-packages/flask/app.py", line 1403, in handle_exception 
reraise(exc_type, exc_value, tb) 
File "/home/user/app/venv/lib/python2.7/site-packages/flask/app.py", line 1817, in wsgi_app 
response = self.full_dispatch_request() 
File "/home/user/app/venv/lib/python2.7/site-packages/flask/app.py", line 1477, in full_dispatch_request 
rv = self.handle_user_exception(e) 
File "/home/user/app/venv/lib/python2.7/site-packages/flask/app.py", line 1381, in handle_user_exception 
reraise(exc_type, exc_value, tb) 
File "/home/user/app/venv/lib/python2.7/site-packages/flask/app.py", line 1475, in full_dispatch_request 
rv = self.dispatch_request() 
File "/home/user/app/venv/lib/python2.7/site-packages/flask/app.py", line 1461, in dispatch_request 
return self.view_functions[rule.endpoint](**req.view_args) 
File "/home/user/app/venv/lib/python2.7/site-packages/flask_admin/base.py", line 60, in inner 
return f(self, *args, **kwargs) 
File "/home/user/app/venv/lib/python2.7/site-packages/flask_admin/base.py", line 60, in inner 
return f(self, *args, **kwargs) 
File "/home/user/app/venv/lib/python2.7/site-packages/flask_admin/base.py", line 60, in inner 
return f(self, *args, **kwargs) 
File "/home/user/app/venv/lib/python2.7/site-packages/flask_admin/model/base.py", line 1182, in index_view 
actions_confirmation=actions_confirmation) 
File "/home/user/app/venv/lib/python2.7/site-packages/flask_admin/base.py", line 254, in render 
return render_template(template, **kwargs) 
File "/home/user/app/venv/lib/python2.7/site-packages/flask/templating.py", line 128, in render_template 
context, ctx.app) 
File "/home/user/app/venv/lib/python2.7/site-packages/flask/templating.py", line 110, in _render 
rv = template.render(context) 
File "/home/user/app/venv/lib/python2.7/site-packages/jinja2/environment.py", line 969, in render 
return self.environment.handle_exception(exc_info, True) 
File "/home/user/app/venv/lib/python2.7/site-packages/jinja2/environment.py", line 742, in handle_exception 
reraise(exc_type, exc_value, tb) 
File "/home/user/app/venv/lib/python2.7/site-packages/flask_admin/templates/admin/model/list.html", line 4, in top-level template code 
{% import 'admin/actions.html' as actionlib with context %} 
File "/home/user/app/venv/lib/python2.7/site-packages/flask_admin/templates/admin/master.html", line 1, in top-level template code 
{% extends admin_base_template %} 
File "/home/user/app/venv/lib/python2.7/site-packages/flask_admin/templates/admin/base.html", line 22, in top-level template code 
{% block page_body %} 
File "/home/user/app/venv/lib/python2.7/site-packages/flask_admin/templates/admin/base.html", line 50, in block "page_body" 
{% block body %}{% endblock %} 
File "/home/user/app/venv/lib/python2.7/site-packages/flask_admin/templates/admin/model/list.html", line 49, in block "body" 
{% block model_list_table %} 
File "/home/user/app/venv/lib/python2.7/site-packages/flask_admin/templates/admin/model/list.html", line 95, in block "model_list_table" 
{% block list_row scoped %} 
File "/home/user/app/venv/lib/python2.7/site-packages/flask_admin/templates/admin/model/list.html", line 118, in block "list_row" 
<td>{{ get_value(row, c) }}</td> 
TypeError: 'unicode' object is not callable 

Любые рекомендации относительно того, как отлаживать это, будут оценены.

Большое спасибо.

Update:

Я нашел ошибку. Это было связано с декоратором @property. В определении модели у меня было два свойства.

@property 
def issue(self): 

    return str(self.description) 

@property 
def __str__(self): 

    return self.issue 

Если удалить @property над ул то ошибка уходит.

https://gist.github.com/bfcondon/8760010

+0

По какой-то причине у вас есть 'get_value', это не функция, а строка' unicode' в шаблонах. Вы используете набор флагов, который меняет 'get_value' глобально? – Joes

+0

Джо, я так не верю. Шаблон генерируется Flask Admin. – bfcondon

+0

Можете ли вы создать изолированный объект, иллюстрирующий проблему? Кроме того, вы можете заполнить отчет об ошибке на http://github.com/mrjoes/flask-admin/ – Joes

ответ

1

Это происходит потому, что колба-Admin хочет __unicode__ строк из моделей на Python 2.

Попробуйте изменить __str__ к __unicode__ в моделях и приложение будет работать. Между тем, я буду обновлять примеры, чтобы быть более совместимыми с Python 2.

На python 3, __str__ не должно быть @property декоратор.