web2py: использование db (...) в модуле - PullRequest
0 голосов
/ 06 июня 2018

Мой файл контроллера становится довольно большим, поэтому я решил начать разбивать его на более мелкие методы и использовать методы для нескольких файлов модулей.Во-первых, это умно?Это способ pythonic / web2py?

В любом случае, я создаю свой первый файл модуля my_module.py в разделе Модули (где уже есть __init__.py).Я определяю метод my_method() в модуле.Я импортирую модуль в свой контроллер: import my_module и вызываю метод в контроллере: my_module.my_method()

контроллер:

import my_module

...

def my_page():
    ...
    my_module.my_method()
    ...

модуль:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
from gluon import *

def my_method():
    ...
    rows = db(db.my_table.my_field == x).select()
    ...

Однако теперь он выдает ошибку:

Файл "/home/my_user/web2py/applications/my_app/controllers/default.py", строка 568, в my_page

my_module.my_method ()

Файл "Applications / my_app / modules / my_module.py", строка 10, в my_method

строки = дБ (db.my_table.my_field == x) .select ()

NameError: глобальное имя 'db' не определено

Я делаю довольно простые вещи базы данных, и метод работал нормально, когда он был определен в самом контроллере.Но почему модуль работает иначе, чем контроллер?Есть ли другие отличия или предостережения?Стоит ли даже использовать модули?

1 Ответ

0 голосов
/ 06 июня 2018

web2py выполняет файлы модели, контроллера и просмотра в подготовленной среде (которая создается заново при каждом HTTP-запросе).Объекты, определенные в файлах модели (включая объект db), добавляются в эту среду и поэтому доступны глобально в любом контроллере или представлении.Однако модули, импортированные в контроллеры, работают так же, как и любой другой модуль Python - они не выполняются в среде web2py, и поэтому объекты в среде web2py не доступны глобально в импортируемых модулях.

В этом случаеУ вас есть пара вариантов.Во-первых, вы можете просто передать объект db в функцию в качестве аргумента:

В модуле:

def my_method(db):

В контроллере:

my_module.my_method(db)

В качестве альтернативы вы можете добавить объект db к объекту current и импортировать current в модуль (как описано здесь ):

В модели:

from gluon import current
current.db = db

В вашем модуле:

from gluon import current

def my_method():
    db = current.db # Keep this inside the function, not at the top level of the module.

Наконец, обратите внимание, что вы также можете получить доступ к любым объектам в среде web2py через словарь current.globalenv, вместо того, чтобы явно добавлять db к current Вы можете просто получить к нему доступ через current.globalenv['db'].

...