2013-06-22 5 views
11

Я создаю простой блог на Flask, и я пытаюсь реализовать Flask-Admin для управления своими сообщениями. Если я иду в админке я могу увидеть список всех мой пост из БД, но когда я пытаюсь создать новый, я получил следующую ошибку:Невозможно создать модели на Flask-admin

Failed to create model. __init__() takes exactly 4 arguments (1 given) 

Это мой пост модель:

class Post(db.Model): 
    __tablename__ = 'news' 
    nid = db.Column(db.Integer, primary_key = True) 
    title = db.Column(db.String(100)) 
    content = db.Column(db.Text) 
    created_at = db.Column(db.DateTime) 

    def __init__(self, title, content): 
     self.title = title.title() 
     self.content = content 
     self.created_at = datetime.datetime.now() 

И это мой код, чтобы добавить модель в пользовательском интерфейсе:

from flask import Flask, session 
from models import db, Post 
from flask.ext.admin import Admin 
from flask.ext.admin.contrib.sqlamodel import ModelView 

app = Flask(__name__) 
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql://root:[email protected]/appname' 
db.init_app(app) 

admin = Admin(app) 
admin.add_view(ModelView(Post, db.session)) 

I DO можно редактировать модели через панель администратора, но не создавать новые. Я знаю, что мне не хватает чего-то действительно глупого, но я не могу понять, что это такое.

Редактировать: он работает, если я не реализую init по модели. Как я могу это исправить?

+3

Колба-Admin может» t создать модель, если у нее есть конструктор с параметрами, отличными от параметров по умолчанию - он не знает, что с ним делать. В этом случае не стесняйтесь переопределять метод create_model (https://github.com/mrjoes/flask-admin/blob/master/flask_admin/contrib/sqlamodel/view.py#L755) и реализовать свою собственную логику создания модели. – Joes

ответ

19

Возьмите взгляд на соответствующая часть в исходном коде для Flask-Admin here.

модель создается без передачи каких-либо аргументов:

model = self.model() 

Таким образом, вы должны поддерживать конструктор, который не принимает никаких аргументов, а также. Например, объявить __init__ конструктор с аргументами по умолчанию:

def __init__(self, title = "", content = ""): 
     self.title = title.title() 
     self.content = content 
     self.created_at = datetime.datetime.now() 
+4

И есть причина для этого - Flask-Admin не может догадаться, какие параметры конструктора модели и что они должны получать в качестве входных данных. – Joes

2

Итак, это то, как я реализовал класс Post в моем приложении:

class Post(db.Model): 
    id = db.Column(db.Integer, primary_key=True) 
    title = db.Column(db.Unicode(80)) 
    body = db.Column(db.UnicodeText) 
    create_date = db.Column(db.DateTime, default=datetime.utcnow()) 
    update_date = db.Column(db.DateTime, default=datetime.utcnow()) 
    status = db.Column(db.Integer, default=DRAFT) 
    user_id = db.Column(db.Integer, db.ForeignKey('user.id')) 


    def __init__(self, title, body, createdate, updatedate, status, user_id): 
     self.title = title 
     self.body = body 
     self.create_date = create_date 
     self.update_date = update_date 
     self.status = status 
     self.user_id = user_id 

Если вы собираетесь придерживаться instanciating модели с created_at значением datetime.datetime.now(), вы можете захотеть ссылаться мой код выше, где эквивалентная функция datetime.utcnow() установлена ​​как значение по умолчанию для create_date и update_date.

Одна вещь, которую мне интересно, это использование вами self.title=title.title() и self.content = content.title(); это те значения, которые исходят из функции?

Если нет, и вы передаете их как строки, я думаю, что вы хотите, чтобы обновить тех self.title = title и self.content = content

Это могло бы объяснить, почему вы видите проблему. Если content.title() не является функцией, которая приведет к отсутствию аргумента для этого параметра ...

вы могли бы попробовать использовать следующее и увидеть, если он решает ваш вопрос:

class Post(db.Model): 
    __tablename__ = 'news' 
    nid = db.Column(db.Integer, primary_key = True) 
    title = db.Column(db.String(100)) 
    content = db.Column(db.Text) 
    created_at = db.Column(db.DateTime, default=datetime.datetime.now()) 

    def __init__(self, title, content, created_at): 
     self.title = title 
     self.content = content 
     self.created_at = created_at 
+0

Я использую title(), чтобы сохранить значение в случае заголовка. На самом деле, я не должен конвертировать контент, ошибка, вызванная слишком многими часами кодирования, я думаю. Дело в том, что у меня такая же проблема для каждой модели, например, в форме регистрации, я не могу получить пароль и сохранить хешированную версию. – nahl

+0

хорошо, давайте попробуем с классом Post для начала; вы пробовали код, который я предлагал? Посмотрите, работает ли это для вас. Мне любопытно, что вы подразумеваете под «Я использую title(), чтобы сохранить значение на титульном листе»? Для чего вы его сохраняете? Куда вы его сохраняете? –

+0

Да, ваш код работает, спасибо. Я сохраняю заголовок сообщения на титульном листе (это заголовок в заголовке). Мне все еще нужно знать, как передать значения формы методу init модели. – nahl

0

Вы должны передавать аргументы по умолчанию в моделях инициализации метод, и он будет создавать модели, как следует:

class Brand(Base): 
    __tablename__ = 'Brand' 
    id  = Column(Integer, primary_key = True) 
    name = Column(String,  default = '') 
    def __init__(self, name = ''): ### default argument passed 
     self.name = name