Невозможно создать модели на 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 на модели. Как я могу это исправить?
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
Вам нужно передать аргумент по умолчанию в метод 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. Например, в моей модели я создаю поле слагов на init. Если я установлю slug="" в init, я должен вручную сделать slug для каждого "сообщения".
Посты, сделанные из CLI, работают, из slug flask_admin пусто, если я не установлю это вручную.
См. Код ниже (slugify - это просто функция, которая удаляет символы, пробелы и т. Д. И создает URL-адреса, поддерживающие 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