2012-02-09 32 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。 A Trial需要保持其test.product_atest.product_b的三元組置換。我現在設置的方式根本不能捕捉到,它看起來真的很不雅。我已經考慮將整數映射到排列,並存儲與排列相對應的整數,但這看起來也不是很好。我對數據庫一無所知,所以我很樂意聽到更好的方式來構建這個數據庫。謝謝!

回答

1

您只需要在其測試的兩種產品的任意組合中持有三種產品參考的試用版?我覺得你的模型定義都很好,但我會用Trial.clean()來驗證每一個(訂單_1,訂單_2,order_3)是(PRODUCT_A,product_b)之一:

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() 
相關問題