I have a small Flask app which uses the populate.obj method for saving form data to an object.
models.py:
class User(db.DynamicDocument):
username = db.StringField(unique=True)
email = db.StringField(unique=True)
role = db.IntField(default=ROLE_USER)
class Post(db.DynamicDocument):
created_at = db.DateTimeField(default=datetime.datetime.now, required=True)
title = db.StringField(max_length=255, required=True)
slug = db.StringField(max_length=255, required=True)
comments = db.ListField(db.EmbeddedDocumentField('Comment'))
author = db.ReferenceField(User)
## various subclasses of BlogPost
...
views.py:
class Detail(MethodView):
decorators = [login_required]
# Map post types to models
class_map = {
'post': BlogPost,
'video': Video,
'image': Image,
'quote': Quote,
}
def get_context(self, slug=None):
if slug:
post = Post.objects.get_or_404(slug=slug)
# Handle old posts types as well
cls = post.__class__ if post.__class__ != Post else BlogPost
form_cls = model_form(cls, exclude=('created_at', 'comments', 'author'))
if request.method == 'POST':
form = form_cls(request.form, inital=post._data)
else:
form = form_cls(obj=post)
else:
# Determine which post type we need
cls = self.class_map.get(request.args.get('type', 'post'))
post = cls()
form_cls = model_form(cls, exclude=('created_at', 'comments', 'author'))
form = form_cls(request.form)
context = {
"post": post,
"form": form,
"create": slug is None
}
return context
if form.validate():
post = context.get('post')
form.populate_obj(post)
post.save()
This works fine. But what I want to do is also save the user object:
...
if form.validate():
post = context.get('post')
form.populate_obj(post)
post(author=MyUserObject) # this fails!
post.save()
This fails with an error:
TypeError: 'BlogPost' object is not callable
I am interested to learn why this is so, and how I should save my user object? I might be demonstrating my ignorance of the populate_obj
method here.
So, the answer seems to be the syntax. This works:
if form.validate():
post = context.get('post')
form.populate_obj(post)
post.author = g.user
post.save()