Django框架多表查询实例分析


Posted in Python onJuly 04, 2018

本文实例讲述了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_nameForeignKey.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程序设计有所帮助。

Python 相关文章推荐
python之wxPython应用实例
Sep 28 Python
MySQL最常见的操作语句小结
May 07 Python
用Python计算三角函数之atan()方法的使用
May 15 Python
python追加元素到列表的方法
Jul 28 Python
python web基础之加载静态文件实例
Mar 20 Python
pycharm 解除默认unittest模式的方法
Nov 30 Python
Django框架模板介绍
Jan 15 Python
python3安装crypto出错及解决方法
Jul 30 Python
Python获取、格式化当前时间日期的方法
Feb 10 Python
为什么说python适合写爬虫
Jun 11 Python
Python编写可视化界面的全过程(Python+PyCharm+PyQt)
May 17 Python
Python合并多张图片成PDF
Jun 09 Python
python 借助numpy保存数据为csv格式的实现方法
Jul 04 #Python
Python将一个CSV文件里的数据追加到另一个CSV文件的方法
Jul 04 #Python
python中csv文件的若干读写方法小结
Jul 04 #Python
Python画柱状统计图操作示例【基于matplotlib库】
Jul 04 #Python
pandas将numpy数组写入到csv的实例
Jul 04 #Python
Python实现的简单排列组合算法示例
Jul 04 #Python
把csv文件转化为数组及数组的切片方法
Jul 04 #Python
You might like
php 函数使用方法与函数定义方法
2010/05/09 PHP
php whois查询API制作方法
2011/06/23 PHP
PHP+swoole+linux实现系统监控和性能优化操作示例
2019/04/15 PHP
关于JavaScript中的关联数组分析
2013/04/09 Javascript
javascript中style.left和offsetLeft的用法说明
2014/03/07 Javascript
javascript 获取元素样式必杀技
2014/05/04 Javascript
js获取url中"?"后面的字串方法
2014/05/15 Javascript
javascript比较两个日期相差天数的方法
2015/07/24 Javascript
jQuery入门基础知识学习指南
2015/08/14 Javascript
详解JavaScript中this关键字的用法
2016/05/26 Javascript
canvas绘制万花筒效果(代码分享)
2017/01/20 Javascript
jQuery中的deferred使用方法
2017/03/27 jQuery
vue-cli构建项目使用 less的方法
2017/10/04 Javascript
微信小程序textarea层级过高(盖住其他元素)问题的解决办法
2019/03/04 Javascript
小程序根据手机机型设置自定义底部导航距离
2019/06/04 Javascript
React组件设计模式之组合组件应用实例分析
2020/04/29 Javascript
[01:03]PWL开团时刻DAY6——别打我
2020/11/05 DOTA
python下调用pytesseract识别某网站验证码的实现方法
2016/06/06 Python
浅谈python对象数据的读写权限
2016/09/12 Python
python join方法使用详解
2019/07/30 Python
python实现批量文件重命名
2019/10/31 Python
Python实现树莓派摄像头持续录像并传送到主机的步骤
2020/11/30 Python
AHAVA美国官方网站:死海海泥护肤品牌
2016/10/18 全球购物
英国健身专家:WIT Fitness
2021/02/09 全球购物
财务会计专业推荐信
2013/11/30 职场文书
给同学的道歉信
2014/01/16 职场文书
图书室管理制度
2014/01/19 职场文书
最新奶茶店创业计划书范文
2014/02/08 职场文书
《自选商场》教学反思
2014/02/14 职场文书
入党积极分子评语
2014/05/04 职场文书
董事长助理工作职责
2014/06/08 职场文书
2014年世界艾滋病日演讲稿
2014/11/28 职场文书
北京爱情故事观后感
2015/06/12 职场文书
红色电影观后感
2015/06/18 职场文书
劳保用品管理制度范本
2015/08/06 职场文书
Java框架入门之简单介绍SpringBoot框架
2021/06/18 Java/Android