2016-01-20 15 views
6

Hardwareのモデルは、さまざまな特性を持つHardwareTypeを持っています。私は新しいHardwareオブジェクトを追加したい場合はDjangoでmodel.Manager.create()メソッドをオーバーライドする方法は?

# models.py 
from django.db import models 

class HardwareType(model.Models): 
    name = models.CharField(max_length=32, unique=True) 

    # some characteristics of this particular piece of hardware 
    weight = models.DecimalField(max_digits=12, decimal_places=3) 
    # and more [...]   

class Hardware(models.Model): 

    type = models.ForeignKey(HardwareType) 

    # some attributes 
    is_installed = models.BooleanField() 
    location_installed = models.TextField() 
    # and more [...] 

、私が最初にHardwareTypeに非常に乾燥していないすべての時間を取得する必要があります:そのような

tmp_hd_type = HardwareType.objects.get(name='NG35001') 
new_hd = Hardware.objects.create(type=tmp_hd_type, is_installed=True, ...) 

したがって、私はオーバーライドに試してみました

# models.py 
from django.db import models 

class HardwareType(model.Models): 
    name = models.CharField(max_length=32, unique=True) 

    # some characteristics of this particular piece of hardware 
    weight = models.DecimalField(max_digits=12, decimal_places=3) 
    # and more [...] 

class HardwareManager(models.Manager): 
    def create(self, *args, **kwargs): 
     if 'type' in kwargs and kwargs['type'] is str: 
      kwargs['type'] = HardwareType.objects.get(name=kwargs['type']) 
     super(HardwareManager, self).create(*args, **kwargs)  

class Hardware(models.Model): 
    objects = HardwareManager() 

    type = models.ForeignKey(HardwareType) 

    # some attributes 
    is_installed = models.BooleanField() 
    location_installed = models.TextField() 
    # and more [...] 

# so then I should be able to do: 
new_hd = Hardware.objects.create(type='ND35001', is_installed=True, ...) 

しかし、私はsの本当にエラーを得続けると:新しいHardwareを作成するときに、自動的にそのようにタイプをインポートする方法HardwareManager.create() ORMからの変則的な振る舞い(私はここにそれらを持っていませんが、必要ならば投稿することができます)。 、

  • マネージャの定義を

    • Hardware.save()メソッドがオーバーライドされるか:私は、DjangoのドキュメントとSOのスレッドで検索したが、ほとんど私は解決策に終わる(私はそこにHardwareTypeを取得する必要があります?) self.create()を呼び出す新しいcreate_somethingメソッド。

    私はまた、コードに掘り始め、ManagerQuerySetのいくつかの特別な種類であることを見ましたが、私はそこから継続するのか分かりません。私は実際にcreateメソッドを置き換えたいと思います。私はこれを管理できないようです。私がやりたいことをやり遂げるのを妨げているのは何ですか?

  • 答えて

    1

    Alasdairの答えからの洞察力は、多くの文字列とUnicode文字列の両方をキャッチするのに役立ったが、実際には欠けていたものをHardwareManager.create()方法でsuper(HardwareManager, self).create(*args, **kwargs)への呼び出しの前にreturn声明でした。私は(コーディングは良いアイデアではないときに疲れている:P)昨日の夜私のテストになっていた

    エラーが私のcreate()方法は持っていなかったので、私はcreate() Dを持っていたnew_hdのその後の利用がNoneだったのでValueError: Cannot assign None: [...] does not allow null values.ましたreturn。どのような愚かな間違い!

    最終的な補正コードは:

    class HardwareManager(models.Manager): 
        def create(self, *args, **kwargs): 
         if 'type' in kwargs and isinstance(kwargs['type'], basestring): 
          kwargs['type'] = HardwareType.objects.get(name=kwargs['type']) 
         return super(HardwareManager, self).create(*args, **kwargs) 
    
    2

    トレースバックを見ることなく、この行に問題があると思います。

    if 'type' in kwargs and kwargs['type'] is str: 
    

    これはkwargs['type']は常にfalseとなりますstrと同じオブジェクトが、あるかどうかをチェックしています。 Pythonの3では

    、 `kwargsから[ '型は']あなたがすべき文字列、あるかどうかを確認するには:

    if 'type' in kwargs and isinstance(kwargs['type'], str): 
    

    あなたはPythonの2を使用している場合は、バイト文字列をキャッチするために、basestringを使用する必要がありますし、ユニコード文字列。

    if 'type' in kwargs and isinstance(kwargs['type'], basestring): 
    
    +0

    私は時間のカップルでこれを試すとエラー(もしあれば)をあなたに戻って取得します。ありがとう! – achedeuzot

    +3

    In。xでは、isinstance(foo、basestring)を使ってunicodeとstrの両方を捕捉することができます。 –

    +0

    @DanielRosemanは、 'Manager.create'をモデルで定義された' model.save'メソッドを使用するかどうかを行いますか? – DhiaTN

    関連する問題