django - 实例化 Django 模型会引发 TypeError : isinstance() arg 2 must be a class, 类型,或类和类型的元组

标签 django django-models

我有一个现有的、功能强大的 Django 应用程序,它在过去几个月一直在 Debug模式下运行。当我将站点更改为在生产模式下运行时,当我点击尝试创建新引用模型对象的特定 View 时,我开始收到发送给我的以下异常电子邮件。

Traceback (most recent call last):

 File "/usr/local/lib/python2.7/dist-packages/Django-1.4.2-py2.7.egg/django/core/handlers/base.py", line 111, in get_response
   response = callback(request, *callback_args, **callback_kwargs)

 File "/usr/local/lib/python2.7/dist-packages/Django-1.4.2-py2.7.egg/django/contrib/auth/decorators.py", line 20, in _wrapped_view
   return view_func(request, *args, **kwargs)

 File "/var/django/acclaimd2/program/api.py", line 807, in put_interview_request
   referral = Referral()

 File "/usr/local/lib/python2.7/dist-packages/Django-1.4.2-py2.7.egg/django/db/models/base.py", line 349, in __init__
   val = field.get_default()

 File "/usr/local/lib/python2.7/dist-packages/Django-1.4.2-py2.7.egg/django/db/models/fields/related.py", line 955, in get_default
   if isinstance(field_default, self.rel.to):

TypeError: isinstance() arg 2 must be a class, type, or tuple of classes and types

如您所见,仅尝试实例化一个 Referral 模型对象就会触发此异常。这是有问题的模型:
class Referral (models.Model):
    opening = models.ForeignKey(Opening,related_name='referrals',null=False,blank=False)
    origin_request = models.ForeignKey('common.request',related_name='referrals',null=True,default=None)
    candidate = models.ForeignKey(User,related_name='referrals',null=False,blank=False)
    intro = models.TextField(max_length=1000,null=False,blank=False)
    experience = models.TextField(max_length=5000,null=False,blank=False)
    email = models.CharField(max_length=255,null=False,blank=False)
    phone = models.CharField(max_length=255,null=False,blank=True,default='')

    def __unicode__(self):
        return u"%s" % self.id

这是 Django 中的错误还是我在不知不觉中做了一些我不应该做的事情?有人对修复或解决方法有任何建议吗?

最佳答案

更新 (下面有解决方案)

我一直在研究 Django 模型代码,似乎有一个错误会在对 ForeignKey 中的相关字段使用基于“app.model”的标识符时创建竞争条件。当应用程序在生产模式而不是 DEBUG 下运行时,上面异常中引用的 ForeignKey.get_default 方法会尝试检查提供的默认值是否是相关字段 (self.rel.to) 的实例:

def get_default(self):
    "Here we check if the default value is an object and return the to_field if so."
    field_default = super(ForeignKey, self).get_default()
    if isinstance(field_default, self.rel.to):
        return getattr(field_default, self.rel.get_related_field().attname)
    return field_default

最初,当使用基于字符串的相关字段实例化 ForeignKey 时,self.rel.to 被设置为基于字符串的标识符。在related.py 中有一个单独的函数叫做add_lazy_relation,在正常情况下,它会尝试将这个基于字符串的标识符转换为模型类引用。因为模型是以惰性方式加载的,所以这种转换可能会推迟到 AppCache 完全加载。

因此,如果在完全填充 AppCache 之前在基于字符串的 ForeignKey 关系上调用 get_default,则可能会引发 TypeError 异常。显然,将我的应用程序置于生产模式足以改变模型缓存的时间,这个错误开始发生在我身上。

解决方案

看起来这确实是 Django 中的一个错误,但是如果您遇到这个问题,这里是如何解决它的。在实例化一个麻烦的模型之前立即添加以下代码片段:
from django.db.models.loading import cache as model_cache
if not model_cache.loaded:
    model_cache._populate()

这会检查 AppCache 上的加载标志以确定缓存是否完全填充。如果不是,我们将强制缓存现在完全填充。而问题将得到解决。

关于django - 实例化 Django 模型会引发 TypeError : isinstance() arg 2 must be a class, 类型,或类和类型的元组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14386536/

相关文章:

python - Stream 中的 CSV 导出(来自 Heroku 上的 Django 管理)

sql - 当顺序很重要时查询成功尝试的分组

django-models - 在不丢失数据的情况下迁移 django-model 字段名称更改

python - 无法弄清楚如何调试这个: ValueError: invalid literal for int() with base 10: '

javascript - 如何将 Geodjango 与 Google Maps API 3 集成?

python - 无法将 DateTimeField 的默认值设置为 "0000-00-00 00:00:00"

python - python中a值<0时如何停止循环

python - Redis 和 Django

Django 按日期排序,但末尾有 "None"?

django - 筛选 PointField 的查询集字段以查找特定距离范围内的项目不正确