避免Django模型中的循环导入(配置类)

避免Django模型中的循环导入(配置类),django,python-3.x,django-models,python-import,Django,Python 3.x,Django Models,Python Import,我已经在django中创建了一个配置模型,以便站点管理员可以动态更改一些设置,但是有些模型依赖于这些配置。我正在使用Django 2.0.2和Python 3.6.4 我在models.py所在的目录中创建了一个config.py文件 让我对代码进行并行编码?Real Enum有更多选项: # models.py from .config import * class Configuration(models.Model): starting_money = models.Intege

我已经在django中创建了一个配置模型,以便站点管理员可以动态更改一些设置,但是有些模型依赖于这些配置。我正在使用Django 2.0.2和Python 3.6.4

我在models.py所在的目录中创建了一个config.py文件

让我对代码进行并行编码?Real Enum有更多选项:

# models.py
from .config import *

class Configuration(models.Model):
    starting_money = models.IntegerField(default=1000)

class Person(models.Model):
    funds = models.IntegarField(default=getConfig(ConfigData.STARTING_MONEY))

# config.py
from .models import Configuration

class ConfigData(Enum):
    STARTING_MONEY = 1
def getConfig(data):
    if not isinstance(data, ConfigData):
        raise TypeError(f"{data} is not a valid configuration type")
    try:
        config = Configuration.objects.get_or_create()
    except Configuration.MultipleObjectsReturned:
        # Cleans database in case multiple configurations exist.
        Configuration.objects.exclude(Configuration.objects.first()).delete()
        return getConfig(data)
    if data is ConfigData.MAXIMUM_STAKE:
        return config.max_stake
如何在没有导入错误的情况下执行此操作?我尝试了绝对导入

您可以通过在getConfigdata函数中加载models.py来推迟加载,因此在加载config.py时不再需要models.py:


因此,我们不在config.py中加载models.py。我们只在实际执行getConfig函数时检查它是否已加载,如果未加载,则在稍后的过程中进行加载。

Willem Van Onsem的解决方案是一个很好的解决方案。我有一种不同的方法,我使用它来处理循环模型依赖关系。我把它作为一个替代解决方案发布在这里,部分原因是我想从经验丰富的python程序员那里得到反馈,看看这种方法是否存在问题

在实用程序模块中,定义以下方法:

from django.apps import apps as django_apps

def model_by_name(app_name, model_name):
  return django_apps.get_app_config(app_name).get_model(model_name)
然后在getConfig中,省略导入并替换该行

config = Configuration.objects.get_or_create()
以下是:

config_class = model_by_name(APP_NAME, 'Configuration')
config = config_class.objects.get_or_create()

绝对进口没有任何好处,因为循环进口仍然存在。您尝试导入需要当前文件才能加载的文件。
config_class = model_by_name(APP_NAME, 'Configuration')
config = config_class.objects.get_or_create()