在Django中创建模型,模型之间可以建立不同的联系,one-to-one relationship,one-to-many relationship,many-to-many relationship,在实际的项目中,往往需要根据一个模型和关系来引用另一个模型对象,接下来我们来看一下这几种关系中,如何相互提取与之想关联的模型
class EntryDetail(models.Model):
entry = models.OneToOneField(Entry, on_delete=models.CASCADE)
details = models.TextField()
ed = EntryDetail.objects.get(id=2)
ed.entry # Returns the related Entry object.
如上面的例子,我们创建了一个与Entry模型(此处未给出代码,大家可以自行想象出一个Entry模型)建立One-to-one relationship关系的EntryDetail模型,如果我们已经拿到一个entrydetail的实例,那么如果我们想要获取与之关联的的Entry实例怎么办呢,这里因为我们通过OneToOneField()函数建立了与entry的一对一关系,只需要通过其中定义的entry即可,那么反过来,如果我们得到的是一个entry模型的实例,如何获取与之相关连的entrydetail的实例呢?
e = Entry.objects.get(id=2)
e.entrydetail # returns the related EntryDetail object
如上图所示,此刻的entrydetail自动变成了entry实例的一个属性,我们直接引用就可以了。
那么对于One-to-many relationship而言,又是怎样的情况呢?
b = Blog.objects.get(id=1)
>>> b.entry_set.all() # Returns all Entry objects related to Blog.
# b.entry_set is a Manager that returns QuerySets.
>>> b.entry_set.filter(headline__contains='Lennon')
>>> b.entry_set.count()
如上图代码所示,这里我们建立了一个和blog模型具有one-to-many(Foreign)关系的模型entry,如果现在我们拿到了一个blog的实例,那么想要获取所有和该blog相关的entry实例,只需要通过entry_set.all()即可获得,该命名是关联模型的名称加上下划线再加一个set即可。
事实上,这个名称并不是固定的,如果我们想要变更该命名,只需要在使用ForeignKey()建立关系的时候添加一个参数related_name来命名即可,如下所示
blog = ForeignKey(Blog, on_delete=models.CASCADE,
related_name='entries')
那么此时关联名称就编程了b.entries.all()了。而反过来,因为一个entry只能对应一个blog,而在其内部也使用blog进行了关联,因此直接使用属性提取的方式就可以解决这个问题了。