使用ListField定义一个不能为空的mongoengine模型

lov*_*esh 5 python mongoengine flask wtforms

我现在用的烧瓶mongoengine和我的模型Post有田title,slug,bodytags.每个Post都有一个独特的slug,每个Post需要至少有1个标签.所以tags是一种liststrings具有至少1个元素.

class Post(db.Document):
    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, unique=True)
    body = db.StringField(required=True)
    tags = db.ListField(db.StringField(max_length=255), required=True)   #each post should have at least one tag

    def get_absolute_url(self):
        return url_for('post', kwargs={"slug": self.slug})

    def __unicode__(self):
        return self.title

    meta = {
        'allow_inheritance': False,
        'indexes': ['-created_at', 'slug', 'title', 'tags'],
        'ordering': ['-created_at'],
        'collection': 'posts',
    }
Run Code Online (Sandbox Code Playgroud)

当我在模板中创建一个用于输入新帖子的表单时,每个标签都会输入一个带有名称的新文本框中,tags因此,如果我有3个标签,Post那么将有3个文本框,每个都有名称.tags 这是视图的方式

from flask.ext.mongoengine.wtf import model_form
class CreateEdit(MethodView):

    form = model_form(Post)    #Gets object of class PostForm which is a subclass of ModelForm, ModelForm is a subclass of Form
    def post(self, slug = None):
        form = self.form(request.form)   #Populate PostForm with data from the request
        post = Post()
        form.populate_obj(post)
        post.save()
        flash('Update successful')
Run Code Online (Sandbox Code Playgroud)

现在我mongoengine.base.ValidationError在浏览器中收到错误.我在帖子请求中传递的数据(Courtesy:Firebug)

title: third post
slug: 3rd
body: this is the 3rd post
tags: third
tags: last
Run Code Online (Sandbox Code Playgroud)

当我在调试器request.form中检查时显示

werkzeug.datastructures.ImmutableMultiDict({'body': u'this is the 3rd post    \r\n  ', 'title': u'third post', 'slug': u'3rd', 'tags': u'third'})
Run Code Online (Sandbox Code Playgroud)

现在tags表格中有多个,但字典中只有一个.这是可以的,因为它是一个字典,所以不能有多个具有相同名称的键.但是,当我检查form.data它显示

{'body': u'this is the 3rd post    \r\n  ', 'title': u'third post', 'created_at': datetime.datetime(2012, 12, 24, 14, 7, 18, 97273), 'tags': [], 'slug': u'3rd'  }
Run Code Online (Sandbox Code Playgroud)

tags字段是一个空的列表,这是荒谬的,因为它应该填充tagsfrom request.form.此外,如果我进入print request.form调试器,我得到

ImmutableMultiDict([('body', u'this is the 3rd post    \r\n  '), ('title', u'third post'), ('slug', u'3rd'), ('tags', u'third'), ('tags', u'last')])
Run Code Online (Sandbox Code Playgroud)

因此,它意味着request对象保留同一名称的多个值,以在representation(__repr__)中显示它,但只将一个值传递给该ModelForm对象.但我ModelForm没有得到任何价值tags.

怎么了?

Smo*_*moe 0

你的代码对我有用

Werkzeug 使用可以包含多个同名键的 MultiDict http://werkzeug.pocoo.org/docs/datastructs/

当我尝试 3 个同名的输入字段并在调试器中检查 request.form 时,我得到:ImmutableMultiDict([('tag', u'1'), ('tag', u'2'), ('tag', u'3')])

并可以得到值request.form.getlist('tag')

难道是因为 Flask/werkzeug 版本太旧了?