获取外键字段时,Django 1.7模型尚未加载

时间:2016-02-15 02:57:39

标签: python django django-1.7

我有一个将由项目__init__.py调用的类(因为我想在django网站启动时将值保存在内存中):

def get_rec(**karg):
    try: 
       if len(karg) == 0:
          return Gateway.objects.all()
       else:
          return Gateway.objects.filter(**karg)
    except as e:
       log.error(e)
       return []

Class test(object):

    def __init_rec_list(object):
        rec = get_rec()
        for r in rec:
            print r.mac_address
            print r.area.area_name

但是在尝试打印r.area.area_name时会出错:

  raise AppRegistryNotReady("Models aren't loaded yet.")
django.core.exceptions.AppRegistryNotReady: Models aren't loaded yet.

为什么不能打印r.area.area_name ??

这是models.py

class Area(models.Model):
    area_name = models.CharField(max_length=255, null=False, blank=False)

class Gateway(models.Model):  
    mac_address = models.CharField(max_length=50, null=False, blank=False)
    area = models.ForeignKey(Area,null=True,blank=True,related_name = 'area')

3 个答案:

答案 0 :(得分:0)

错误说清楚 - 模型尚未准备好。您可以触及数据库的时间早于AppConfig.ready,但它仍有一些限制。

如果您想安全地使用所有模型,请将代码放入项目根目录中的urls.py

答案 1 :(得分:0)

通过在__init__.py文件中调用模型,您将创建一个鸡蛋和鸡蛋场景。初始化代码需要准备好模型,模型正在等待__init__.py准备就绪。

__init__.py文件中调用此类代码并不是一个好习惯。因为此文件不仅适用于django启动,还适用于导入模块时。

从您的代码中,我可以看到您正在尝试访问用户ip和其他信息。

最好的方法是使用自定义middleware拦截request/response并根据值更新request/response对象。

与此类似的东西 -

class CustomMiddleware(object):
    def process_request(self, request):
        rec = get_rec()
        request.rec = rec;

现在,您可以访问rec的{​​{1}}媒体资源,无论如何都可以使用。

您可以在此处阅读有关中间件的更多信息 -

https://docs.djangoproject.com/en/1.7/topics/http/middleware/

答案 2 :(得分:0)

你应该在django加载后调用django相关的初始化代码。只有当django.setup()运行时,App注册表才准备就绪。

正确的入口点(假设您有默认的wsgi.py文件)位于wsgi.py中:

import os
from django.core.wsgi import get_wsgi_application
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "mysite.settings")    
application = get_wsgi_application() # this prepares django 
my_init_code()

如果您在模型加载之前绝对需要运行,请使用直接SQL到数据库。