I'm creating a simple blog on Flask and I'm trying to implement Flask-Admin to manage my posts. If I go to the admin area I can see a list of all my post from the DB but when I try to create a new one I got the next error:
Failed to create model. __init__() takes exactly 4 arguments (1 given)
This is my post model:
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()
And this is my code to add the model to the 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))
I DO can edit models through the admin panel but not create new ones. I know I'm missing something really stupid but I can't figure out what it is.
Edit: it works if I don't implement init on the model. How can I fix this?
Take a look at the relevant part in the source code for Flask-Admin here.
The model is created without passing any arguments:
model = self.model()
So you should support a constructor that takes no arguments as well. For example, declare your __init__
constructor with default arguments:
def __init__(self, title = "", content = ""):
self.title = title.title()
self.content = content
self.created_at = datetime.datetime.now()
So, this is how I've implemented a Post class in my application:
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
If you're going to stick with instanciating your model with a created_at
value of datetime.datetime.now()
, you may want to reference my code above, wherein the equivalent datetime.utcnow()
function is set as the default for create_date
and update_date
.
One thing I'm curious about is your use of self.title=title.title()
and self.content = content.title()
; are those values coming from a function?
If not and you're passing them as strings, I think you'd want to update those to self.title = title
and self.content = content
That could explain why you're seeing your issue. If content.title()
isn't a function, that would result in no argument for that parameter...
you might try using the following and seeing if it resolves your issue:
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With