2013-01-17 22 views
8

我有一個現有的功能性Django應用程序,它在過去的幾個月裏一直以DEBUG模式運行。當我將網站更改爲在生產模式下運行時,當我點擊試圖創建新的引用模型對象的特定視圖時,我開始收到以下異常電子郵件。實例化Django模型引發TypeError:isinstance()arg 2必須是類和類的類,類型或元組

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 

正如您所看到的,僅嘗試實例化引用模型對象就會觸發此異常。這是有問題的模式:

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的錯誤還是我在不知不覺中做一些我不應該?任何人有任何修復或解決方法的建議?

+0

發生了什麼'put_interview_request interview_request_json ['email'])'? –

+0

INSTALLED_APPS中是否有一個名爲'common'的應用程序?它是否有'請求'模型? –

+0

@AbidA - 對不起,我開始嘗試解決該問題之後的一個堆棧跟蹤版本。我更新了第一個片段以反映適當的堆棧跟蹤。 –

回答

13

UPDATE(下面的解決方案)

我已經挖成的Django模型代碼,它好像有,使用「app.model」爲主的標識符時會自動創建一個競爭條件的錯誤ForeignKey中的相關字段。當應用程序在生產模式下運行而不是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異常。顯然,將我的應用程序轉化爲生產模式足以改變模型緩存的時間,這個錯誤開始發生在我身上。

SOLUTION

看來這是真的在Django的錯誤,但這裏是如何繞過它,如果你曾經遇到這個問題。立即添加以下代碼片段實例化一個棘手的模型前:

from django.db.models.loading import cache as model_cache 
if not model_cache.loaded: 
    model_cache._populate() 

此檢查在應用程序緩存加載的標誌,以確定是否緩存,如果完全填充。如果不是,我們將強制緩存完全填充。問題將得到解決。

+2

謝謝!我遇到過同樣的問題。這是否已作爲Django的入場券提交?我在https://code.djangoproject.com/ticket/上找不到任何東西。 – ferrouswheel

+2

這是令人討厭的。在將網站遷移到自定義用戶模型時遇到此問題。彷彿在這個過程中沒有足夠的問題。但是,是的,從硬鏈接到'用戶'到'settings.AUTH_USER_MODEL'導致鎖定。我在我的所有models.py文件和shazaam中加載了這些文件,它可以工作。 – Oli

+0

這在django 1.8中不起作用,儘管只要你調用了django.setup() – craigds

1

另一個原因:

確保所有外鍵都在同一個應用程序(APP標籤)相同的參考模型。這一次我在牆上撞了一會兒。

class Meta: 
    db_table = 'reservation' 
    app_label = 'admin' 
+0

就可以解決Django 1.8中的原始錯誤。是的另一個原因:在你的模型上有一個流氓的'abstract = True'。 –

相關問題