2017-09-30 1 views
0

私はモデルモデルを持っています。このモデルには複数の属性があり、そのうち3つはdomaintld,subdomain,url-OneToOneFieldです。Djangoモデルのフィールドサブセットから1つだけのフィールドを許可します

私はこれらのフィールドから1つだけを空ではないようにしようとしています。

私のアプローチはうまくいきましたが、もっと良い方法があれば分かりました(私はPostgreSQLを使用しています)。

あなたは models.pyにこのような何かを持っていると仮定すると
def save(self, force_insert=False, force_update=False, using=None, update_fields=None): 
    self.clean() 
    super(Model, self).save(force_insert, force_update, using, update_fields) 

def clean(self): 
    super(Model, self).clean() 

    if not(((bool(self.url)^bool(self.domaintld))^bool(self.subdomain)) and not(self.url and self.domaintld and self.subdomain)): 
     raise exceptions.ValidationError("One and only one field can be used: url,domaintld,subdomain") 

答えて

0

class DomainTLD(models.Model): 
    # attributes and methods 

class Subdomain(models.Model): 
    # attributes and methods 

class URL(models.Model): 
    # attributes and methods 

class MyModel(models.Model): 
    domaintld = models.OneToOneField(DomainTLD) 
    subdomain = models.OneToOneField(Subdomain) 
    url = models.OneToOneField(URL) 
    # other attributes and methods 

私はこのようなジャンゴcontenttypesとリファクタリングを使用することをお勧めしたい:

class MyModel(models.Model): 
    content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE) 
    object_id = models.PositiveIntegerField() 
    content_object = GenericForeignKey('content_type', 'object_id') 

をしてsavecleanをスクラップ方法。今MyModelは、いずれのモデルと関係を持っていることDomainTLDSubdomainまたはURLすることができます - モデルにcontent_typeポイント、object_idは、データベース内のフィールドになっていないであろう、オブジェクトIDとcontent_objectを保持するオブジェクトを取得するために使用されます。

これははるかにクリーンな方法であり、その不明瞭なcleanメソッドを取り除くことができます。 これをさらに強化し、content_typeの選択肢を希望するものに限定することができます。このSO answerはこれを説明しています。

関連する問題