2016-05-05 4 views
0

データのサブセットのみを含むdjangoモデルで外部キーまたはOneToOne関係を定義することはできますか?データのサブセットを持つDjangoモデルForeignKey

例:

私には2つのモデルがあります。

@with_author 
    class Product(models.Model): 
     GTIN = models.CharField(max_length=30) 
     material = models.ForeignKey(Material, on_delete=models.PROTECT) 

     UOM = models.OneToOneField(MaterialUOM) 
     defaultPrice = MoneyField(max_digits=10, decimal_places=2, default_currency='USD') 

@with_author 
    class UOM(models.Model): 
     uomname = models.CharField(max_length=30) 
     material = models.ForeignKey(Material, on_delete=models.PROTECT) 

ので、私は唯一の製品と同じ材料値を持つUOM値を許可するように私の製品モデルにしたいです。

モデルレベルや他の場所で可能であり、ドロップダウンに関連性のない値を表示しないでください。

答えて

0

モデルのclean() methodにいくつかの検証を追加することによって、この制約を適用することができます。ような何か:

from django.core.exceptions import ValidationError 

class Product(models.Model): 
    GTIN = models.CharField(max_length=30) 
    material = models.ForeignKey(Material, on_delete=models.PROTECT) 

    UOM = models.OneToOneField(MaterialUOM) 
    defaultPrice = MoneyField(max_digits=10, decimal_places=2, default_currency='USD') 

    def clean(self): 
     if not self.material == self.UOM.material: 
      # This will cause the model not to be saved and report an error 
      raise ValidationError('Material does not match UOM material') 

あなたのモデルに編集を処理するためにModelFormを使用している場合は、その後、clean()は、フォーム検証の一部として自動的に呼び出されます。コード内でモデルを直接変更する場合は、モデルを保存する前に自分で呼び出す必要があります。ドキュメントには、これについて詳しく説明しています。

あなたが二重に確認したい場合は、override the save() methodことができます。

def save(self, *args, **kwargs): 
    if not self.material == self.UOM.material: 
     return # Model is not saved 
    super(Product, self).save(*args, **kwargs) 

これは、すべてのエラーを報告しません - それだけでモデルを保存しません。したがって、上記のclean()メソッドを使用する必要があります。

+0

'clean()'メソッドは、 'ModelForm'を使用してモデルを保存するときにのみ呼び出され、それ以外の場合は呼び出されません。私は 'save'メソッドをオーバーライドすることは他のケースをカバーする方が良いと思います。そして、エラーに関しては、これをカスタム化することができます。 – AKS

+0

これは機能しませんモデルでもフォームに素材がないので、フォームレベルできれいに追加できません。モデルにクリーンアップを追加すると、エラーが発生します。例外タイプ:\t RelatedObjectDoesNotExist 例外値:\t 製品には物質がありません。 –

+0

保存レベルを上書きしても、私のドロップダウンにはすべての値が表示されます。 –

関連する問題