如何填充使用mongokit / pymongo的平台选择字段? [英] How to populate wtform select field using mongokit/pymongo?

查看:203
本文介绍了如何填充使用mongokit / pymongo的平台选择字段?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

  

我试图用mongodb查询创建一个SelectField,但是到目前为止我还没有成功: #格式在蓝图中
CATEGORIES = []
为db.Terms.find()中的项目:
CATEGORIES.append((item ['slug'],item ['name' ]))


TermForm(Form):
category = SelectField(
choices = CATEGORIES,
validators = [Optional()])

但我得到一个异常:

<$ p $回溯(最近一次调用的最后一个):
在< module>文件中,第14行的文件/home/one/Projects/proj/manage.py
app = create_app(os.getenv('FLASK_CONFIG')或'default')
文件/home/one/Projects/proj/app/__init__.py,第27行,在create_app
from app.term.models import Term,TermCategory
文件/home/one/Projects/proj/app/term/__init__.py,第5行,在< module>
来自。导入视图
文件/home/one/Projects/proj/app/term/views.py,第7行,在< module>从.forms中导入
TermForm,CategoryForm
在< module>文件中的/home/one/Projects/proj/app/term/forms.py,第48行。
用于db.Terms.find()中的项目:
文件/home/one/.venv/proj/lib/python3.4/site-packages/flask_mongokit.py,第238行,在__getattr__
self.connect()
文件/home/one/.venv/proj/lib/python3.4/site-packages/flask_mongokit.py,第196行,连接
host = ctx.app.config.get('MONGODB_HOST'),
AttributeError:'NoneType'对象没有属性'app'

如果有人能够对这个问题进行更多的阐述,我会非常感激。

解决方案

看到这个答案的底部,你真正想要的是,这第一部分只是解释你得到的直接错误。






您正在运行的代码依赖于此类上下文之外的应用程序上下文。您需要在应用程序上下文中运行填充 CATEGORIES 的代码,以便Flask-MongoKit db可以获得连接。



看起来您正在使用应用程序工厂,所以重构您的代码以便在创建应用程序时可以填充集合(您需要访问应用程序以设置上下文)。



将代码放在一个函数中,然后在上下文中导入并调用该函数。

 #forms.py 

CATEGORIES = []

def init():
for db.Terms.find()
CATEGORIES.append((item ['slug'],item ['name']))

#添加到create_app函数(甚至导入)

def create_app(conf):
#...
from app.term import form
$ b with app.app_context():
forms.init()
$ ...

如果您使用的是蓝图,则可以添加一个执行当蓝图被注册时,所以应用程序工厂不需要知道所有的细节。将所有导入如 views 移到此注册函数中。

 #在app / term / __ init__.py 
#的底部#假设蓝图叫做bp

@ bp.record_once
def register(state):
with state.app.app_context():
from。导入表单,视图






然而,这些都不是或许你在这种情况下实际上想要的是什么。它看起来像试图动态地将表单字段的选项设置为数据库中的当前值。如果您现在这样做,则在应用程序启动时会填充一次,即使数据库条目更改也不会更改。你真正希望做的是在窗体的 __ init __ 方法中设置选项。



<$

$ _ $ __init __(self,* args,** kwargs):
class TestForm(Form):
category = SelectField() db.Terms.find()]
中的item的self.category.kwargs ['choices'] = [(item ['slug'],item ['name'])___ init __(self,* args ,** kwargs)


I'm trying to create a SelectField using a mongodb query, but so far I haven't been successful:

# forms.py in blueprint
CATEGORIES = []
for item in db.Terms.find():
    CATEGORIES.append((item['slug'], item['name']))


class TermForm(Form):
    category = SelectField(
        choices=CATEGORIES,
        validators=[Optional()])

But I get an exception:

Traceback (most recent call last):
  File "/home/one/Projects/proj/manage.py", line 14, in <module>
    app = create_app(os.getenv('FLASK_CONFIG') or 'default')
  File "/home/one/Projects/proj/app/__init__.py", line 27, in create_app
    from app.term.models import Term, TermCategory
  File "/home/one/Projects/proj/app/term/__init__.py", line 5, in <module>
    from . import views
  File "/home/one/Projects/proj/app/term/views.py", line 7, in <module>
    from .forms import TermForm, CategoryForm
  File "/home/one/Projects/proj/app/term/forms.py", line 48, in <module>
    for item in db.Terms.find():
  File "/home/one/.venv/proj/lib/python3.4/site-packages/flask_mongokit.py", line 238, in __getattr__
    self.connect()
  File "/home/one/.venv/proj/lib/python3.4/site-packages/flask_mongokit.py", line 196, in connect
    host=ctx.app.config.get('MONGODB_HOST'),
AttributeError: 'NoneType' object has no attribute 'app'

If anyone could shed a little more light upon the subject, I would be very appreciative.

解决方案

See the bottom of this answer for what you really want, this first section is just to explain the immediate error you're getting.


You are running code that depends on an application context outside of such a context. You'll need to run the code that populates CATEGORIES inside an application context so that the Flask-MongoKit db can get a connection.

It looks like you're using an application factory, so refactor your code a bit so that you can populate the collection while creating the app (you need access to the app to set up a context).

Put the code inside a function, then import and call that function in the factory within a context.

# forms.py

CATEGORIES = []

def init():
    for item in db.Terms.find():
        CATEGORIES.append((item['slug'], item['name']))

# add to create_app function (even the import)

def create_app(conf):
    #...
    from app.term import forms

    with app.app_context():
        forms.init()
    #...

If you you're using blueprints, you can add a function that executes when the blueprint is registered, so the app factory doesn't need to know about all the details. Move all imports such as views to inside this registration function. The changes from above are not needed.

# at the bottom of app/term/__init__.py
# assuming blueprint is called bp

@bp.record_once
def register(state):
    with state.app.app_context():
        from . import forms, views


However, neither of these are probably what you actually want in this case. It looks like you're trying to dynamically set the choices for a form field to the current values in the database. If you do this as you are now, it will be populated once when the app starts and then never change even if the database entries change. What you really want to do is set the choices in the form's __init__ method.

class TestForm(Form):
    category = SelectField()

    def __init__(self, *args, **kwargs):
        self.category.kwargs['choices'] = [(item['slug'], item['name']) for item in db.Terms.find()]
        Form.__init__(self, *args, **kwargs)

这篇关于如何填充使用mongokit / pymongo的平台选择字段?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆