如何将查询结果发送到WTForm字段?

0 投票
1 回答
969 浏览
提问于 2025-04-18 03:58

我在用SQLalchemy管理博客文章的标签,标签和文章之间是多对多的关系。我需要帮助把标签的值显示到一个可以编辑的文本框里。现在我显示出来的是查询的内容。

模型

标签和文章之间的关系在`tags`里定义。

class Tag(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(50), unique=True)
url = db.Column(db.String(120), unique=True)

def __init__(self, name, url):
    self.name = name
    self.url = url

class Post(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    title = db.Column(db.String(80))
    body = db.Column(db.Text)
    pub_date = db.Column(db.DateTime)
    tags = db.relationship('Tag', secondary=posts_tags, backref='posts', lazy='dynamic')


class Tag(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(50), unique=True)
    url = db.Column(db.String(120), unique=True)

我遇到的问题是,在WTF中显示标签字段时,它在字段里显示的是查询,而不是结果。

我想到两个解决办法,但不知道怎么做……

a.) 在视图中遍历标签并显示值。
b.) 在一个自定义字段中,想办法传递文章的ID,然后在渲染字段之前运行一个查询。类似这样……

这个字段的黑科技可以用,但我不知道怎么动态传递文章ID到字段里。

class TagListField(Field):
    widget = TextArea()

    def _value(self):
        q = Post.query.join(posts_tags, (posts_tags.c.post_id == {{ NEED HELP HERE}}))
        taglist = []
        for p in q:
            for t in p.tags:
                taglist.append(t.name)
        taglist
        return ", ".join(taglist)

    def process_formdata(self, valuelist):
        if valuelist:
            self.data = [x.strip() for x in valuelist[0].split(',')]
        else:
            self.data = []

希望能看到视图和字段的选项……谢谢!

1 个回答

3

你使用 _value 的方式不对,它是用来显示数据的,而不是用来设置数据的。

数据是设置在表单上的,而不是在字段上。

class TagListField(Field):
    widget = TextInput()

    def _value(self):
        if self.data:
            return u', '.join(self.data)
        else:
            return u''

    def process_formdata(self, valuelist):
        if valuelist:
            self.data = [x.strip() for x in valuelist[0].split(',')]
        else:
            self.data = []


class PostForm(Form):
    title = StringField(u'title', validators=[DataRequired()])
    body = StringField(u'Text', widget=TextArea())
    pub_date = DateTimeField(u'date create')
    topic = QuerySelectField(query_factory=enabled_topics, allow_blank=True)
    tags = TagListField(u'Tags') # here you use your custom field

    # a method to set the tags
    def fill_tags(self, tags):
        self.tags.data = tags
    # and from the view that is creating the form you send the list of tags

在你的视图中:

form = PostForm()
form.fill_tags([tag.name for tag in post.tags.all()])

撰写回答