获取外键字段时尚未加载 Django 1.7 模型
Django 1.7 Models aren't loaded yet when getting foreign key field
我有一个 Class 将被项目调用 __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')
错误说得很清楚 - 模型尚未准备好。较早可以接触数据库的时刻在 AppConfig.ready,但它仍有一些限制。
如果您想安全地使用所有模型,请将代码放入项目根目录中的urls.py
。
通过在 __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;
现在您可以访问 request
的 属性 rec
并随意使用。
您可以在此处阅读有关中间件的更多信息 -
https://docs.djangoproject.com/en/1.7/topics/http/middleware/
您应该在 Django 加载后调用依赖于 Django 的初始化代码。仅当django.setup() 运行s时,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 到数据库。
我有一个 Class 将被项目调用 __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')
错误说得很清楚 - 模型尚未准备好。较早可以接触数据库的时刻在 AppConfig.ready,但它仍有一些限制。
如果您想安全地使用所有模型,请将代码放入项目根目录中的urls.py
。
通过在 __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;
现在您可以访问 request
的 属性 rec
并随意使用。
您可以在此处阅读有关中间件的更多信息 -
https://docs.djangoproject.com/en/1.7/topics/http/middleware/
您应该在 Django 加载后调用依赖于 Django 的初始化代码。仅当django.setup() 运行s时,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 到数据库。