如何在不将 DJANGO_SETTINGS_MODULE 设置为环境变量的情况下创建 Django 包?
How to create a django package without setting DJANGO_SETTINGS_MODULE as environment variable?
我正在创建一个本身使用 Django 的包,我将在其他 Django 应用程序中使用它。我面临的主要问题是出于各种原因(例如日志记录和其他广泛的要求)我需要使用设置。因为,这个包没有任何 views/urls,我们正在编写测试并使用 pytest 来 运行 它们。如果没有配置设置,测试将不会 运行。所以最初我将以下代码片段放在根应用程序的 __init__
文件中。
import os
import django
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "my_package.settings")
django.setup()
现在,测试 运行 正常并且作为独立应用程序的包正在运行。但是当我将它安装到主项目中时,它 覆盖 具有自己设置的环境变量,您可以想象它会随之而来的那种破坏。
这是我第一次打包django 应用程序。所以我不精通最佳实践,而且文档有点令人费解。我阅读了在其包中使用设置的各种包的结构和代码,但我仍然无法理解如何确保包访问预期的设置并且项目的设置不会同时受到影响。
在浏览文档时,我遇到了设置 DJANGO_SETTINGS_MODULE
的替代方法,如下所示:
from django.conf import settings
settings.configure(DEBUG=True)
但是我到底应该在哪里添加呢?对于导入设置的每个文件或它是否会在 __init__
中工作(试过这个但有些地方不对,显示应用程序未加载)
我也试过这个,我将我的设置导入为默认值并使用它们作为默认值调用配置并调用 django.setup() 但没有成功:
# my_package/__init__.py
from django.conf import settings
from my_package import settings as default
if not settings.configured:
settings.configure(default_settings=default, DEBUG=True)
import django
django.setup()
此外,我需要设置主要是因为在使用该包的项目中我几乎没有可以覆盖的参数。安装包后,覆盖的变量是我在 运行 时间内应该能够在包中访问的内容。
如果有人可以指导如何解决这个问题或者有更好的创建需要 django 设置的包的过程,请分享。
所以我最终找到了一种无需将设置模块设置为环境变量即可工作的方法。这使我能够通过导入所有覆盖的设置以及来自以下位置的默认设置来使用指定的设置:
创建一个应用程序文件以将您的程序包配置为应用程序。
# my_package/apps.py
from django.apps import AppConfig
class MyPackageConfig(AppConfig):
name = 'my_package'
verbose_name = 'My package'
并且,在您的包的根目录中。 __init__.py
中的以下代码段将仅设置覆盖的设置:
# my_package/__init__.py
from django.conf import settings
import django
from my_package import settings as overridden_settings
from django.conf import settings
default_app_config = 'my_package.apps.MyPackageConfig'
if not settings.configured:
# Get the list of attributes the module has
attributes = dir(overridden_settings)
conf = {}
for attribute in attributes:
# If the attribute is upper-cased i.e. a settings variable, then copy it into conf
if attribute.isupper():
conf[attribute] = getattr(overridden_settings, attribute)
# Configure settings using the settings
settings.configure(**conf)
# This is needed since it is a standalone django package
django.setup()
参考 django.setup()
将做什么:
https://docs.djangoproject.com/en/2.2/topics/settings/#calling-django-setup-is-required-for-standalone-django-usage
注意事项:
- 因为它在
__init__
中,这将确保如果您从包中导入某些内容,则设置已配置。
- 如上述文档所述,您必须确保只配置一次设置,并且类似地调用一次设置方法,否则会引发异常。
让我知道这是否有帮助,或者您能想出更好的解决方案。
我正在创建一个本身使用 Django 的包,我将在其他 Django 应用程序中使用它。我面临的主要问题是出于各种原因(例如日志记录和其他广泛的要求)我需要使用设置。因为,这个包没有任何 views/urls,我们正在编写测试并使用 pytest 来 运行 它们。如果没有配置设置,测试将不会 运行。所以最初我将以下代码片段放在根应用程序的 __init__
文件中。
import os
import django
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "my_package.settings")
django.setup()
现在,测试 运行 正常并且作为独立应用程序的包正在运行。但是当我将它安装到主项目中时,它 覆盖 具有自己设置的环境变量,您可以想象它会随之而来的那种破坏。
这是我第一次打包django 应用程序。所以我不精通最佳实践,而且文档有点令人费解。我阅读了在其包中使用设置的各种包的结构和代码,但我仍然无法理解如何确保包访问预期的设置并且项目的设置不会同时受到影响。
在浏览文档时,我遇到了设置 DJANGO_SETTINGS_MODULE
的替代方法,如下所示:
from django.conf import settings
settings.configure(DEBUG=True)
但是我到底应该在哪里添加呢?对于导入设置的每个文件或它是否会在 __init__
中工作(试过这个但有些地方不对,显示应用程序未加载)
我也试过这个,我将我的设置导入为默认值并使用它们作为默认值调用配置并调用 django.setup() 但没有成功:
# my_package/__init__.py
from django.conf import settings
from my_package import settings as default
if not settings.configured:
settings.configure(default_settings=default, DEBUG=True)
import django
django.setup()
此外,我需要设置主要是因为在使用该包的项目中我几乎没有可以覆盖的参数。安装包后,覆盖的变量是我在 运行 时间内应该能够在包中访问的内容。
如果有人可以指导如何解决这个问题或者有更好的创建需要 django 设置的包的过程,请分享。
所以我最终找到了一种无需将设置模块设置为环境变量即可工作的方法。这使我能够通过导入所有覆盖的设置以及来自以下位置的默认设置来使用指定的设置:
创建一个应用程序文件以将您的程序包配置为应用程序。
# my_package/apps.py
from django.apps import AppConfig
class MyPackageConfig(AppConfig):
name = 'my_package'
verbose_name = 'My package'
并且,在您的包的根目录中。 __init__.py
中的以下代码段将仅设置覆盖的设置:
# my_package/__init__.py
from django.conf import settings
import django
from my_package import settings as overridden_settings
from django.conf import settings
default_app_config = 'my_package.apps.MyPackageConfig'
if not settings.configured:
# Get the list of attributes the module has
attributes = dir(overridden_settings)
conf = {}
for attribute in attributes:
# If the attribute is upper-cased i.e. a settings variable, then copy it into conf
if attribute.isupper():
conf[attribute] = getattr(overridden_settings, attribute)
# Configure settings using the settings
settings.configure(**conf)
# This is needed since it is a standalone django package
django.setup()
参考 django.setup()
将做什么:
https://docs.djangoproject.com/en/2.2/topics/settings/#calling-django-setup-is-required-for-standalone-django-usage
注意事项:
- 因为它在
__init__
中,这将确保如果您从包中导入某些内容,则设置已配置。 - 如上述文档所述,您必须确保只配置一次设置,并且类似地调用一次设置方法,否则会引发异常。
让我知道这是否有帮助,或者您能想出更好的解决方案。