Невозможно создать модели на 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))
Я могу редактировать модели через Панель администратора, но не создавать новые. Я знаю, мне чего-то не хватает. глупо, но я не могу понять, что это.
Edit: он работает, если я не реализую init на модель. Как я могу это исправить?
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()
Итак, вот как я реализовал класс 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
вам нужно передать аргумент по умолчанию в models 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
это проблема и для меня. Передача значений по умолчанию работает, но не если вы хотите пользовательское значение, которое вы не хотите изменять в flask_admin. Например, в моей модели я делаю поле slug на init. Если я установил его в slug=" "в init, я должен вручную сделать slug для каждого"post".
сообщения, сделанные из работы CLI, из flask_admin slug пуст, если я не установил его вручную.
см. код ниже (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
