Невозможно создать модели на 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:pass@localhost/appname'
db.init_app(app)

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

Я ДЕЙСТВИТЕЛЬНО могу редактировать модели через панель администратора, но не могу создавать новые. Я знаю, что упускаю что-то действительно глупое, но я не могу понять, что это такое.

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


person nahl    schedule 22.06.2013    source источник
comment
Flask-Admin не может создать модель, если у него есть конструктор с нестандартными параметрами - он не знает, что с ним делать. В этом случае вы можете переопределить метод create_model (github.com/mrjoes/flask-admin/blob/master/flask_admin/contrib/) и реализовать собственную логику создания модели.   -  person Joes    schedule 23.06.2013


Ответы (4)


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

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

    model = self.model()

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

    def __init__(self, title = "", content = ""):
        self.title = title.title()
        self.content = content
        self.created_at = datetime.datetime.now()
person Miguel    schedule 22.06.2013
comment
И на то есть причина — Flask-Admin не может угадать, что такое параметры конструктора модели и что они должны получать на входе. - person Joes; 28.06.2013
comment
Ссылка битая QQ - person Jerome; 13.09.2020

Итак, вот как я реализовал класс 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
person One Bad Panda    schedule 22.06.2013
comment
Я использую title(), чтобы сохранить значение в заголовке. На самом деле мне не следует преобразовывать контент, я думаю, это ошибка, вызванная слишком большим количеством часов кодирования. Дело в том, что у меня одна и та же проблема на каждой модели, поэтому, например, в регистрационной форме я не могу получить пароль и сохранить его хешированную версию. - person nahl; 23.06.2013
comment
хорошо, давайте попробуем для начала с классом Post; Вы пробовали код, который я предложил? Посмотрите, работает ли это для вас. Мне любопытно, что вы имеете в виду, говоря, что я использую title() для сохранения значения в заголовке? Для чего вы его сохраняете? Куда вы его сохраняете? - person One Bad Panda; 23.06.2013
comment
Да, ваш код работает, спасибо. Я храню заголовок сообщения в заголовке (это заголовок сообщения в заголовке). Мне все еще нужно знать, как передать значения формы в метод инициализации модели. - person nahl; 23.06.2013

Вам нужно передать аргумент по умолчанию в метод 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
person Ilja    schedule 10.09.2015

Это проблема и для меня. Передача значений по умолчанию работает, но не в том случае, если вам нужно пользовательское значение, которое вы не хотите изменять в flask_admin. Например, в моей модели я создаю поле slug при инициализации. Если я установлю slug="" в инициализации, мне придется вручную создавать слаг для каждого "сообщения".

Сообщения, сделанные из CLI, работают, слаг из flask_admin пуст, если я не установил его вручную.

См. код ниже (slugify — это всего лишь функция, которая удаляет символы, пробелы и т. д. и создает слаги, удобные для URL-адресов).

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
person j Rodr    schedule 30.05.2018