本文实例讲述了Django框架多表查询。分享给大家供大家参考,具体如下:
多表查询是模型层的重要功能之一, Django提供了一套基于关联字段独特的解决方案.
ForeignKey
来自Django官方文档的模型示例:
from django.db import models class Blog(models.Model): name = models.CharField(max_length=100) tagline = models.TextField() class Author(models.Model): name = models.CharField(max_length=50) email = models.EmailField() class Entry(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()
class ForeignKey
ForeignKey字段接受一个Model类作为参数, 类型与被参照的字段完全相同:
blog = models.ForeignKey(Blog)
ForeignKey.to_field
关联到的关联对象的字段名称。默认地,Django 使用关联对象的主键。
blog = models.ForeignKey(Blog, to_field=Blog.name)
ForeignKey.db_constraint
Django Model的ForeignKey字段的主要功能是维护一个一对多的关系, 以进行关联查询.
只有在db_constraint=True
时Django model才会在数据库上建立外键约束, 在该值为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 # Returns the related Blog object.
修改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() # "UPDATE blog_entry SET blog_id = NULL ...;"
Django提供了一种使用双下划线__
的查询语法:
> Entry.objects.filter(blog__name='Beatles Blog')
反向查询
被索引的关系模型可以访问所有参照它的模型的实例,如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官网的示例:
from django.db import models class Person(models.Model): name = models.CharField(max_length=50) class Group(models.Model): name = models.CharField(max_length=128) members = models.ManyToManyField(Person, through='Membership', through_fields=('group', 'person')) class Membership(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)
class ManyToManyField
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() # Returns all members objects for this Group.
反向查询:
>a = Person.objects.get(id=1) >a.group_set.all()
同样related_name可以设置反向查询集的名称。
添加删除关联
因为ManyToManyField自动维护关联表,程序员不便于直接访问.ManyToManyField提供了API用于添加和删除关联(即through表中的记录).
使用一个自动维护through表的模型作为示例:
class User(models.Model): user_id = models.IntegerField(primary_key=True) class Flight(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) if flights.count() != 0: flight = flights[0] users = User.objects.filter(id=user_id) if users.count() != 0: user = users[0]
通过拥有关联字段的Flight实例进行添加关联操作:
flight.reserve.add(user) flight.save()
删除操作与这类似:
flight.reserve.remove(user) flight.save()
希望本文所述对大家基于Django框架的Python程序设计有所帮助。
Django框架,多表查询
稳了!魔兽国服回归的3条重磅消息!官宣时间再确认!
昨天有一位朋友在大神群里分享,自己亚服账号被封号之后居然弹出了国服的封号信息对话框。
这里面让他访问的是一个国服的战网网址,com.cn和后面的zh都非常明白地表明这就是国服战网。
而他在复制这个网址并且进行登录之后,确实是网易的网址,也就是我们熟悉的停服之后国服发布的暴雪游戏产品运营到期开放退款的说明。这是一件比较奇怪的事情,因为以前都没有出现这样的情况,现在突然提示跳转到国服战网的网址,是不是说明了简体中文客户端已经开始进行更新了呢?
更新动态
- 凤飞飞《我们的主题曲》飞跃制作[正版原抓WAV+CUE]
- 刘嘉亮《亮情歌2》[WAV+CUE][1G]
- 红馆40·谭咏麟《歌者恋歌浓情30年演唱会》3CD[低速原抓WAV+CUE][1.8G]
- 刘纬武《睡眠宝宝竖琴童谣 吉卜力工作室 白噪音安抚》[320K/MP3][193.25MB]
- 【轻音乐】曼托凡尼乐团《精选辑》2CD.1998[FLAC+CUE整轨]
- 邝美云《心中有爱》1989年香港DMIJP版1MTO东芝首版[WAV+CUE]
- 群星《情叹-发烧女声DSD》天籁女声发烧碟[WAV+CUE]
- 刘纬武《睡眠宝宝竖琴童谣 吉卜力工作室 白噪音安抚》[FLAC/分轨][748.03MB]
- 理想混蛋《Origin Sessions》[320K/MP3][37.47MB]
- 公馆青少年《我其实一点都不酷》[320K/MP3][78.78MB]
- 群星《情叹-发烧男声DSD》最值得珍藏的完美男声[WAV+CUE]
- 群星《国韵飘香·贵妃醉酒HQCD黑胶王》2CD[WAV]
- 卫兰《DAUGHTER》【低速原抓WAV+CUE】
- 公馆青少年《我其实一点都不酷》[FLAC/分轨][398.22MB]
- ZWEI《迟暮的花 (Explicit)》[320K/MP3][57.16MB]