Django Related objects

  在使用django时,在模型定义的关系中,如果使用到了ForeignKey, OneToOneField, 或者 ManyToManyField,那么该模型的实例,就有了便捷的API去访问相关的对象。

在使用django时,在模型定义的关系中,如果使用到了ForeignKey, OneToOneField, 或者 ManyToManyField,那么该模型的实例,就有了便捷的API去访问相关的对象。

使用的模型:

from django.db import models
class Blog(models.Model):
    name = models.CharField(max_length=100)
    tagline = models.TextField()

    # On Python 3: def __str__(self):
    def __unicode__(self):
        return self.name
class Author(models.Model):
    name = models.CharField(max_length=50)
    email = models.EmailField()

    # On Python 3: def __str__(self):
    def __unicode__(self):
        return self.name
class Entry(models.Model):
    blog = models.ForeignKey(Blog)
    headline = models.CharField(max_length=255)
    body_text = models.TextField()
    pub_date = models.DateField()
    mod_date = models.DateField()
    authors = models.ManyToManyField(Author)
    n_comments = models.IntegerField()
    n_pingbacks = models.IntegerField()
    rating = models.IntegerField()

    # On Python 3: def __str__(self):
    def __unicode__(self):
        return self.headline


1、外键的便捷API

    例如:

?
1
2
>>> e  =  Entry.objects.get( id = 2 )
>>> e.blog   # 通过这种方式,就能获取到外键blog对象

    如果你想改变关联的外键,也很简单,如:

?
1
2
3
  >>> e  =  Entry.objects.get( id = 2 )
  >>> e.blog  =  Blog()
  >>> e.save()   # 这一步是必须的,只有调用了save后,才会将改变的结果更新到数据库

    如果在定义外键时,设置null=True,则还可以这么写:e.blog=None

    注:Forward access to one-to-many relationships is cached the first time the related object is accessed. Subsequent accesses to the foreign key on the same object instance are cached.

    如:

?
1
2
3
  >>> e  =  Entry.objects.get( id = 2 )
  >>>  print (e.blog)   # Hits the database to retrieve the associated Blog.
  >>>  print (e.blog)   # Doesn't hit the database; uses cached version.

    select_related()方法,获取实例所有相关的模型对象,并缓存起来,在通过外键关系、一对多关系访问对象时,不会再造成数据库访问。

    如果一个模型含有外键,该模型的外键的实例对象就有访问Manager管理器的权限,默认情况下,这个管理器的名字是xxx_set, xxx是外键模型名称的小写;这个Manager会返回一个QuerySets,这个QuerySets可以像其他的QuerySet一样,使用各种方法进行操作,如filter()等。

如:

?
1
2
3
4
5
6
>>> b  =  Blog.objects.get( id = 1 )
>>> b.entry_set. all ()  # 返回所有和当前Blog有关联的Entry的集合
 
# b.entry_set 是一个包含了QuerySet的Manager模型管理器
>>> b.entry_set. filter (headline__contains = 'Lennon' )
>>> b.entry_set.count()

    同样的,你也可以设置xxx_set的访问名称,通过在定义外键时,加上related_name,like this :blog=models.Foreign(Blog, related_name='entries'),那么代码就成了这样:

?
1
2
>>> b  =  Blog.objects.get( id = 1 )
>>> b.entries. all ()  # 返回所有和当前Blog有关联的Entry的集合

    另外,对于上面提到的QuerySet还有如下一些方法,可供使用,如add()、create()、remove()、clear()等。

2、Many-to-many 关系

    和外键约束类似,处理many-to-many关系,在后台处理上是去维护两个一对多的关联关系,这两个一对多的关系在访问上不同的是:定义了多对多关系属性的模型对象,通过属性直接访问,被关联的模型在访问时,就要使用:小写的模型名称_set的方式进行访问(这里和外键是一样的访问方式);如下:

?
1
2
3
4
5
6
7
=  Entry.objects.get( id = 3 )
e.authors. all ()  # 返回所有Entry关联的素有Author
e.authors.count()
e.authors. filter (name__contains = 'John' )
 
=  Author.objects.get( id = 5 )
a.entry_set. all ()  # 返回Author所有关联的Entry

    同样的,many-to-many关联关系同样可以通过related_name来指定访问名称。

3、one-to-one关系

    如下:

?
1
2
3
4
5
class  EntryDetail(models.Model):
     entry  =  models.OneToOneField(Entry)
     details  =  models.TextField()
ed  =  EntryDetail.objects.get( id = 2 )
ed.entry  # Returns the related Entry object.

    在访问‘反转’模型的方式上唯一不同的是:一对一返回的是一个实例对象,而非结果集,所以,对应的'反转'模型就有一个模型名称对应的属性(全小写),如下:

?
1
2
=  Entry.objects.get( id = 2 )
e.entrydetail  # returns the related EntryDetail object

    注:If no object has been assigned to this relationship, Django will raise a DoesNotExist exception.

4、关联关系上的查询

    涉及到相关关系查询时,其查询规则和普通查询类似,当指定查询条件时。可以是主键值或者实例对象;如:

?
1
2
3
Entry.objects. filter (blog = b)  # Query using object instance
Entry.objects. filter (blog = b. id # Query using id from instance
Entry.objects. filter (blog = 5 # Query using id directly

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值