2016-06-08 38 views
-1

的利弊在Django tutorial它模拟一个民意调查结构:什么ForeignKey的,而不是ManyToManyField

from django.db import models 

class Question(models.Model): 
    question_text = models.CharField(max_length=200) 
    pub_date = models.DateTimeField('date published') 


class Choice(models.Model): 
    question = models.ForeignKey(Question, on_delete=models.CASCADE) 
    choice_text = models.CharField(max_length=200) 
    votes = models.IntegerField(default=0) 

,但我一直不知道他们为什么不实现象多对多关系:

from django.db import models 

class Question(models.Model): 
    question_text = models.CharField(max_length=200) 
    pub_date = models.DateTimeField('date published') 
    choices = models.ManyToManyField(Choice) 

class Choice(models.Model): 
    choice_text = models.CharField(max_length=200) 
    votes = models.IntegerField(default=0) 

优缺点都有什么?

+3

他们是完全不同的东西,外键是一对多的关系。 – Sayse

+0

是的,我知道。但为什么他们选择ForeignKey?一个问题有很多选择和相同的选择可以用在许多问题 – somenxavier

回答

1

我确定他们在本教程中使用了ForeignKey(一对多)关系,因为他们试图让示例尽可能简单,只有两个模型:QuestionChoice。请注意,votesChoice模型的一个字段,可以非常简单地显示投票结果。

如果您正在进行民意调查,您对每个问题(非常同意,有些同意等)有相同的选择,那么ManyToMany关系可能是适当的。但是这会让事情更加复杂。您建议的ManyToMany关系模型为:

from django.db import models 

class Question(models.Model): 
    question_text = models.CharField(max_length=200) 
    pub_date = models.DateTimeField('date published') 
    choices = models.ManyToManyField(Choice) 

class Choice(models.Model): 
    choice_text = models.CharField(max_length=200) 
    votes = models.IntegerField(default=0) 

但是,如果不进行某些更改,则无法正常工作。 votes仍然是Choice表的字段,但现在每个选择都适用于很多问题。你可以看到强烈同意的选择有38票,但是你不知道选民同意哪些问题。为了能够正确地投票结果制成表格,你将不得不做一些像

from django.db import models 

class Question(models.Model): 
    question_text = models.CharField(max_length=200) 
    pub_date = models.DateTimeField('date published') 
    choices = models.ManyToManyField('Choice', through='QuestionChoices') 

class Choice(models.Model): 
    choice_text = models.CharField(max_length=200) 

class QuestionChoices(models.Model): 
    question = models.ForeignKey(Question, on_delete=models.CASCADE) 
    choice = models.ForeignKey(Choice, on_delete=models.CASCADE) 
    votes = models.IntegerField(default=0) 

现在你可以制表到底有多少人投了每一个问题,选择组合,但它更复杂,不太适合让开始的教程。

使用您建议的ManyToMany模型,Django会在幕后自动创建QuestionChoices模型,但为了将votes字段附加到它,您必须自己明确地执行此操作。

如果您的关系可以建模为OneToMany或ManyToMany,则优点和缺点取决于您的特定应用程序。一般而言,您希望使用最能准确反映真实生活情况的模型。但是,您还必须考虑如何更新和汇总数据,并尝试达成最佳折中方案。根据我的经验,选择困难的情况并不多。

+0

非常感谢。这是关于理论和实际问题的非常详细的描述 – somenxavier