Не удалось создать модели на Flask-admin

Я создаю простой блог на 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()

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

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))

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

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

Ответ 1

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

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

    model = self.model()

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

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

Ответ 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

Если вы собираетесь внедрить свою модель с 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

Ответ 3

Вам необходимо передать аргумент по умолчанию в методах 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