2013-01-17 4 views
8

私は、過去数ヶ月間DEBUGモードで動作していた既存の機能的なDjangoアプリケーションを持っています。プロダクションモードで実行するようにサイトを変更すると、新しいReferralモデルオブジェクトを作成しようとする特定のビューにヒットしたときに、次のExceptionの電子メールが私に送信されるようになります。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 

これはジャンゴのバグですか、私は知らないうちにその私はべきではない何かをやっていますか?誰でも修正や回避策の提案はありますか?

+0

'put_interview_request interview_request_json ['email'])'ではどうなりますか? –

+0

INSTALLED_APPSに「共通」と呼ばれるアプリがありますか?そのアプリに「リクエスト」モデルがありますか? –

+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が完全に取り込まれる前にget_defaultが文字列ベースのForeignKeyリレーションで呼び出された場合、TypeError例外が発生する可能性があります。どうやら私のアプリケーションをプロダクションモードにすることは、このエラーが発生し始めたモデルキャッシングのタイミングを変えるだけのものでした。

SOLUTION

本当にジャンゴのバグであるようだが、ここであなたが今までにこの問題が発生しない場合、それを回避する方法です。あなたが面倒なモデルをインスタンス化する直前に次のコードスニペットを追加します。

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

これは完全に実装されている場合場合はキャッシュを決定するためにAppCacheにロードされたフラグをチェック。そうでない場合は、キャッシュを強制的に完全に作成します。そして問題は解決されます。

+2

ありがとう!私も同じ問題がありました。これはDjangoのチケットとして提出されていますか?私はhttps://code.djangoproject.com/ticket/で何かを見つけることができませんでした – ferrouswheel

+2

これは*そう*迷惑です。サイトをカスタムユーザーモデルに移行する際にこれが発生しました。あたかもそのプロセスに十分な問題がないかのように。しかし、ええ、ハードリンクから 'User'への' settings.AUTH_USER_MODEL'への移動はロックアップを引き起こしました。私はすべてのmodels.pyファイルとshazaamにこれらの負荷を投げ捨てました。 – Oli

+0

これはdjango 1.8では動作しませんが、django.setup()を呼び出していれば、元のバグはDjango 1.8で修正される可能性があります。 – craigds

1

別の原因:

は、すべての外部キーは、同じアプリケーション(アプリのラベル)の同じ参照モデルであることを確認します。私はこの壁の上でしばらくの間、壁に向かって頭を叩いていた。

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

もう一つの原因:モデルに不正な 'abstract = True'があります。 –

関連する問題