首页 > 解决方案 > django 中跨多个应用程序的一个对象

问题描述

前段时间我开始学习 python,我创建了命令行应用程序来管理你的家庭酒吧和鸡尾酒食谱(你可以添加酒精瓶,添加食谱,检查你是否有成分来创建给定的鸡尾酒等等),它使用 sqlite3 数据库. 调用BarmanShell的类是这个应用程序的一种 api,其中包含用户可以使用的每个功能。

__init__该类的包含基于 xml 文件的数据库连接和数据验证。

现在,当我学习 django 时,我想在这个应用程序的 web 版本中重用它。在这个 django 项目中,我有myshelf必须使用某些BarmanShell功能的应用程序。

def myshelf_view(request, *args, **kwargs):
    if request.method == "GET":
       barman = BarmanShell()
       shelf = barman.getShelf()
       # do some things to create context based on shelf

barman = BarmanShell()只能执行一次,而不是每个 GET 请求。但我不能把它从myshelf_view功能上移开

barman = BarmanShell()
def myshelf_view(request, *args, **kwargs):
    if request.method == "GET":
       shelf = barman.getShelf()
       # do some things to create context based on shelf

因为它包含一些 sql 查询并产生以下错误:

SQLite objects created in a thread can only be used in that same thread.

另外,我无法将其创建移动到django_project/urls.py然后将其导入myshelf/views.py

barman = BarmanShell() # in urls.py
from django_project.urls import barman # in views.py

因为它给出了一个错误

 ImportError: cannot import name 'barman' from partially initialized module 'django_project.urls' (most likely due to a circular import)

有没有办法只创建一次该对象,然后在 django 中重用它,而不需要进行大BarmanShell的重构,例如使所有函数静态化?

BarmanShell 类的 MWE:

class BarmanShell:
    def __init__(self):
        self.conn = sqlite3.connect("db.sqlite3")
        self.cur = self.conn.cursor()
        self.cur.execute('''CREATE TABLE IF NOT EXISTS SHELF
                                (ID   INTEGER,
                                 NAME TEXT     NOT NULL,
                                 QTY  INTEGER  NOT NULL,
                                 PRIMARY KEY(ID, NAME));''')
        self.conn.commit()

    def getShelf(self):
        return self.cur.execute("SELECT NAME, QTY FROM SHELF").fetchall()

标签: pythondjangoimport

解决方案


我想如果你正确连接你的数据库一切都应该工作,这段代码对我有用。

#url.py
from django.db import connection
class BarmanShell(object):
    def __init__(self):
        self.cur = connection.cursor()
        self.cur.execute('''CREATE TABLE IF NOT EXISTS SHELF
                                (ID   INTEGER,
                                 NAME TEXT     NOT NULL,
                                 QTY  INTEGER  NOT NULL,
                                 PRIMARY KEY(ID, NAME));''')

        self.cur.execute('''INSERT OR REPLACE INTO SHELF VALUES (1, 'Margo', 43);''')
        
    def getShelf(self):
        return self.cur.execute("SELECT NAME, QTY FROM SHELF").fetchall()

bn = BarmanShell()
print(id(bn))

urlpatterns = [    
    path('', views.myshelf_view, kwargs={'barman':bn}, name='myshelf_view'),
]
#views.py
def myshelf_view(request, **kwargs): 
    print(id(kwargs.get('barman'))) 
    print(kwargs.get('barman').getShelf())
OUTPUT:
ID_OF_BARMAN_OBJECT
ID_OF_BARMAN_OBJECT
[('Margo', 43)]

对象只创建一次。


推荐阅读