13

我正在 Flask 上创建一个简单的博客,并且正在尝试实施 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()

这是我将模型添加到 UI 的代码:

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:pass@localhost/appname'
db.init_app(app)

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

我可以通过管理面板编辑模型,但不能创建新模型。我知道我错过了一些非常愚蠢的东西,但我无法弄清楚它是什么。

编辑:如果我不在模型上实现init ,它会起作用。我怎样才能解决这个问题?

4

4 回答 4

21

在此处查看 Flask-Admin 源代码中的相关部分。

该模型是在不传递任何参数的情况下创建的:

    model = self.model()

所以你应该支持一个不带参数的构造函数。例如,__init__使用默认参数声明您的构造函数:

    def __init__(self, title = "", content = ""):
        self.title = title.title()
        self.content = content
        self.created_at = datetime.datetime.now()
于 2013-06-22T23:46:38.173 回答
3

所以,这就是我在我的应用程序中实现 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

如果您要坚持使用 的created_at值来实例化您的模型datetime.datetime.now(),您可能需要参考我上面的代码,其中等效datetime.utcnow()函数被设置为create_dateand的默认值update_date

我很好奇的一件事是您对self.title=title.title()and的使用self.content = content.title();这些值来自函数吗?

如果不是,并且您将它们作为字符串传递,我认为您希望将它们更新为self.title = titleself.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
于 2013-06-22T22:22:08.760 回答
0

这对我来说也是一个问题。传递默认值有效,但如果您想要一个不想在 flask_admin 中更改的自定义值,则不能。一个例子是,在我的模型中,我在 init 上创建了一个 slug 字段。如果我在初始化中将它设置为 slug="",我必须手动为每个“帖子”制作 slug。

除非我手动设置,否则由 CLI 工作的帖子来自 flask_admin slug 是空白的。

请参见下面的代码(slugify 只是一个去除字符、空格等并生成对 url 友好的 slug 的函数)。

class Article(Base):
    __tablename__ = "articles"

    id = Column(Integer, primary_key=True)
    posted_time = Column(DateTime(timezone=True))
    updated_time = Column(DateTime(timezone=True))
    image = Column(String(200))
    article_title = Column(String(200))
    article_body = Column(String)
    slug = Column(String(100), unique=True)

    tags = relationship("ArticleTag", secondary=tags, backref="articles")
    categories = relationship("ArticleCategory", secondary=categories, backref="articles")

    def __init__(self, article_title="", posted_time=None, updated_time=None, image="", article_body="", slug=""):
        self.slug = slugify(article_title)
        self.article_title = article_title
        self.posted_time = posted_time
        self.updated_time = updated_time
        self.image = image
        self.article_body = article_body
于 2018-05-30T17:32:38.077 回答
0

您需要在模型init方法中传递默认参数,它将按应有的方式创建模型:

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
于 2015-09-10T00:53:39.340 回答