2012-02-09 9 views
0

私はDjangoでブラインドテストのプロジェクトを進めています。データベース構造のベストプラクティスについて知りたいと思います。ForeignKeysの順列を保持するDjangoモデルを表現する

class Product(models.Model): 
    name = models.CharField(max_length=200) 

class Test(models.Model): 
    product_a = models.ForeignKey(Product, related_name='a_products') 
    product_b = models.ForeignKey(Product, related_name='b_products') 

class Trial(models.Model): 
    test = models.ForeignKey(Test) 

    # Is there a more elegant way to represent the fact that these three 
    # variables are all a permutation of test.product_a and test.product_b? 
    order_1 = models.ForeignKey(Product, related_name='orders_1') 
    order_2 = models.ForeignKey(Product, related_name='orders_2') 
    order_3 = models.ForeignKey(Product, related_name='orders_3') 

私のモデルはおおよそ次のように設定されています。ここでは

は私がいる問題を実証するための私のコードの簡易版です。単一のTestには多くのTrialsがあります。 Trialは、test.product_atest.product_bの3要素置換を保持する必要があります。私が今設定している方法では、それはまったく捕捉されません。そして、それは本当にうらやましいようです。私は整数を順列にマッピングし、その順列に対応する整数を格納することを考えましたが、それはどちらかといえば素晴らしいとは言えません。私はデータベースについて全く知らないので、これをより良い方法で構築したいと思っています。ありがとう!

答えて

1

テストの2つの製品の任意の組み合わせで3つの製品リファレンスを保持するだけで試用する必要がありますか?私はあなたのモデル定義は大丈夫だと思うが、私は(order_1、order_2、order_3)のそれぞれは(PRODUCT_A、product_b)の一つであることを検証するためにTrial.clean()を使用します。今

def clean(self): 
    super(Trial, self).clean() 
    for order in (order_1, order_2, order_3): 
    if order not in (self.test.product_a, self.test.product_b): 
     raise ValidationError("Order not one of test's products.") 

、に差がある場合を除きテストとそのproduct_aとの関係、そのテストとproduct_bとの関係、私は本当に多くのものか​​ら多くのものになるはずだと思います。試用品関係についても同様です。あなたの基準に合った値が設定されていることを確認することができます。

class Test(models.Model): 
    products = models.ManyToManyField(Product, related_name='tests') 
    def clean(self): 
    super(Test, self).clean() 
    if self.products.all().count() != 2: 
     raise ValidationError('Test should have 2 products') 

class Trial(models.Model): 
    test = models.ForeignKey(Test) 
    orders = models.ManyToManyField(Product, related_name='trials') 
    def clean(self): 
    super(Trial, self).clean() 
    if self.orders.all().count() != 3: 
     raise ValidationError('Trial should have 3 orders') 
    for product in self.orders.all(): 
     if product not in self.test.products.all(): 
     raise ValidationError("Order not one of test's products") 

私はあなたのrelated_namesも変更しました。それらは逆の関係に使用されるため、使用する特定の製品に関連する試用版とテスト版を入手するには:

product = //some Product 
trials = product.trials.all() 
tests = product.tests.all() 
関連する問題