Django 数据库关系 - 多对多、一对多
我在理解Django中的多对一和多对多关系时,总是感到有些困惑。我知道它们在SQL和数据库中的工作原理,也明白外键的概念,但有些地方还是不太明白。
在多对多关系中,双方都可以自动访问对方,就像是一个“反向”的一对多关系。但是,我还是无法从概念上完全理解这一点。
多对一的例子:
class Reporter(models.Model):
first_name = models.CharField(max_length=30)
last_name = models.CharField(max_length=30)
email = models.EmailField()
def __unicode__(self):
return u"%s %s" % (self.first_name, self.last_name)
class Article(models.Model):
headline = models.CharField(max_length=100)
pub_date = models.DateField()
reporter = models.ForeignKey(Reporter)
def __unicode__(self):
return self.headline
class Meta:
ordering = (’headline’,)
我可以这样做:
>>> r = Reporter(first_name=’John’, last_name=’Smith’, email=’john@example.com’)
>>> r.save()
>>> a = Article(id=None, headline="This is a test", pub_date=datetime(2005, 7, 27), reporter=r)
>>> a.save()
>>> a.reporter
<Reporter: John Smith>
所以,我可以通过外键从文章类访问记者类。
多对多的例子:
class Publication(models.Model):
title = models.CharField(max_length=30)
def __unicode__(self):
return self.title
class Meta:
ordering = (’title’,)
class Article(models.Model):
headline = models.CharField(max_length=100)
publications = models.ManyToManyField(Publication)
def __unicode__(self):
return self.headline
class Meta:
ordering = (’headline’,)
我的问题是——我可以通过文章类上的ManyToManyField访问出版物类,就像我在多对一的例子中那样。那么,多对多和多对一有什么不同呢?我还能用多对多做些什么?(当然,我也可以在两者之间进行反向访问,但我现在想暂时忽略反向关系,以免让我更困惑。)
为了更好地表达我的问题,通常在多对多关系中还能做些什么,而在多对一关系中又做不到呢?
声明一下——我刚开始学习编程,已经读过Django官方文档中关于模型的整整100页,所以请不要再把我引导回去。如果可以的话,我已经在从中学习了。
另外,我对代码的理解更好,所以如果可以的话,请包含一些代码示例。
1 个回答
1
一个记者可以写很多文章,但一篇文章只能有一个记者。
# This will get the reporter of an article
article.reporter
# This will get all the articles of a reporter
reporter.article_set.all()
# You cannot add another reporter to an article
article.reporter.add(r) # This will raise an Error!
另一方面,
一篇文章可以有很多出版物,而一份出版物也可以与很多文章有关联。
# This will get all the publications of an article
article.publications.all()
# This will get all the related articles of a publication
publication.article_set.all()
# You CAN add another publication to an article
article.publications.add(p) # No Error here