Django框架多表查询实例分析
本文实例讲述了Django框架多表查询。分享给大家供大家参考,具体如下:
多表查询是模型层的重要功能之一,Django提供了一套基于关联字段独特的解决方案.
ForeignKey
来自Django官方文档的模型示例:
fromdjango.dbimportmodels classBlog(models.Model): name=models.CharField(max_length=100) tagline=models.TextField() classAuthor(models.Model): name=models.CharField(max_length=50) email=models.EmailField() classEntry(models.Model): blog=models.ForeignKey(Blog) authors=models.ManyToManyField(Author) headline=models.CharField(max_length=255) body_text=models.TextField() pub_date=models.DateField() mod_date=models.DateField() n_comments=models.IntegerField() n_pingbacks=models.IntegerField() rating=models.IntegerField()
classForeignKey
ForeignKey字段接受一个Model类作为参数,类型与被参照的字段完全相同:
blog=models.ForeignKey(Blog)
ForeignKey.to_field
关联到的关联对象的字段名称。默认地,Django使用关联对象的主键。
blog=models.ForeignKey(Blog,to_field=Blog.name)
ForeignKey.db_constraint
DjangoModel的ForeignKey字段的主要功能是维护一个一对多的关系,以进行关联查询.
只有在db_constraint=True时Djangomodel才会在数据库上建立外键约束,在该值为False时不建立约束.
默认db_constraint=True.
ForeignKey.related_name
这个名称用于让关联的对象反查到源对象.
如果你不想让Django创建一个反向关联,请设置related_name为'+'或者以'+'结尾.
ForeignKey.related_query_name以ForeignKey.related_name作为默认值,两者功能的具体说明请参见相关文档
使用ForeignKey查询
前向查询
若关系模型A包含与模型B关联的关联字段,模型A的实例可以通过关联字段访问与其关联的模型B的实例:
>>>e=Entry.objects.get(id=2) >>>e.blog#ReturnstherelatedBlogobject.
修改e.blog并调用save方法存入数据库
>>>e.blog=some_blog >>>e.save()
如果ForeignKey字段有null=True设置(即它允许NULL值),可以分配None来删除对应的关联性
>>>e=Entry.objects.get(id=2) >>>e.blog=None >>>e.save()#"UPDATEblog_entrySETblog_id=NULL...;"
Django提供了一种使用双下划线__的查询语法:
>>>Entry.objects.filter(blog__name='BeatlesBlog')
反向查询
被索引的关系模型可以访问所有参照它的模型的实例,如Entry.blog作为Blog的外键,默认情况下Blog.entry_set是包含所有参照Blog的Entry示例的查询集,可以使用查询集API取出相应的实例。
>>>b=Blog.objects.get(id=1) >>>b.entry_set.all()
Entry.blog的related_name和related_query_name可以设置该查询集的名字。
ManyToManyField
来自Django官网的示例:
fromdjango.dbimportmodels classPerson(models.Model): name=models.CharField(max_length=50) classGroup(models.Model): name=models.CharField(max_length=128) members=models.ManyToManyField(Person,through='Membership',through_fields=('group','person')) classMembership(models.Model): group=models.ForeignKey(Group) person=models.ForeignKey(Person) inviter=models.ForeignKey(Person,related_name="membership_invites") invite_reason=models.CharField(max_length=64)
classManyToManyField
ManyToManyField.through
Django会自动创建一个表来管理多对多关系,若要手动指定关联表则需要使用through关键字参数.
ManyToManyField.through_fields
上文示例中Membership有两个外键指向Person(person和inviter),这使得关联关系含混不清并让Django不知道使用哪一个。
在这种情况下,必须使用through_fields明确指定Django应该使用哪些外键
through_fields接收一个二元组('field1','field2'),其中field1为指向定义ManyToManyField字段的模型的外键名称(本例中为group),field2为指向目标模型的外键的名称(本例中为person).
ManyToManyField.db_table
默认情况下,关联表的名称使用多对多字段的名称和包含这张表的模型的名称以及Hash值生成,如:memberShip_person_3c1f5
若要想要手动指定表的名称,可以使用db_table关键字参数指定.
others
下列API和ForeignKey中的同名API相同.
- ManyToManyField.db_constraint
- ManyToManyField.related_name
- ManyToManyField.related_query_name
使用ManyToManyField查询
多对多关系和ForeignKey具有相似的API.
>>>e=Group.objects.get(id=3) >>>e.members.all()#ReturnsallmembersobjectsforthisGroup.
反向查询:
>>>a=Person.objects.get(id=1) >>>a.group_set.all()
同样related_name可以设置反向查询集的名称。
添加删除关联
因为ManyToManyField自动维护关联表,程序员不便于直接访问.ManyToManyField提供了API用于添加和删除关联(即through表中的记录).
使用一个自动维护through表的模型作为示例:
classUser(models.Model): user_id=models.IntegerField(primary_key=True) classFlight(models.Model): flight_id=models.IntegerField(primary_key=True) reserve=models.ManyToManyField(User,related_name='flight_reserve')
首先获得要进行关联的Flight和User实例:
flights=Flight.objects.filter(flight_id=flight_id) ifflights.count()!=0: flight=flights[0] users=User.objects.filter(id=user_id) ifusers.count()!=0: user=users[0]
通过拥有关联字段的Flight实例进行添加关联操作:
flight.reserve.add(user) flight.save()
删除操作与这类似:
flight.reserve.remove(user) flight.save()
希望本文所述对大家基于Django框架的Python程序设计有所帮助。