前言

前面在admin后台页面通过设置外键,可以选择下拉框的选项,本篇主要讲解关于外键(ForeignKey)的查询

models设计

在上一篇的基础上新增一个BankName表,Card表通过外键关联到BankName

class BankName(models.Model):
'''银行信息'''
bank_name = models.CharField(max_length=50, verbose_name="银行名称", default="")
city = models.CharField(max_length=30, verbose_name="城市", default="")
point = models.CharField(max_length=60, verbose_name="网点", default="") class Meta:
verbose_name = '银行'
verbose_name_plural = verbose_name def __str__(self):
return self.bank_name class Card(models.Model):
'''银行卡 基本信息'''
card_id = models.CharField(max_length=30, verbose_name="卡号", default="")
card_user = models.CharField(max_length=10, verbose_name="姓名", default="")
add_time = models.DateField(auto_now=True, verbose_name="添加时间")
bank_info = models.ForeignKey(BankName, on_delete=models.CASCADE, default="") class Meta:
verbose_name = "银行卡账户_基本信息"
verbose_name_plural = '银行卡账户' def __str__(self):
return self.card_id class CardDetail(models.Model):
'''银行卡详情信息'''
card = models.OneToOneField(Card,
on_delete=models.CASCADE,
verbose_name="卡号"
)
tel = models.CharField(max_length=30, verbose_name="电话", default="")
mail = models.CharField(max_length=30, verbose_name="邮箱", default="")
city = models.CharField(max_length=10, verbose_name="城市", default="")
address = models.CharField(max_length=30, verbose_name="详细地址", default="") class Meta:
verbose_name = "账户_个人资料"
verbose_name_plural = verbose_name def __str__(self):
return self.card.card_user

之后执行 makemigrations 和migrate,同步数据

python manage.py makemigrations

python manage.py migrate

shell模式新增测试

为了调试方便,可以使用django的shell模式,对表的数据增删改查操作,打开cmd,cd到manage.py目录

python manage.py shell

先新增数据测试数据

D:\web_djo\helloworld>python manage.py shell

>>> from hello.models import Card, BankName
>>> a = BankName.objects.create(bank_name='上海银行', city='上海', point='徐家汇区')
>>> a.save
>>> c = Card.objects.create(card_id='62270121022100000', card_user='张三', bank_info=a)
>>> c.save

正向查询

根据Card表的card_id,去查询关联的对应的BankName相关信息,这个相对来说简单一点

>>> from hello.models import BankName, Card
>>> cardxx=Card.objects.get(card_id='62270121022100000')
>>> cardxx.card_user
'张三' >>> cardxx.bank_info
<BankName: 上海银行> >>> cardxx.bank_info.bank_name
'上海银行'
>>> cardxx.bank_info.city
'上海'
>>>

反向查询_set

如果想通过银行名称“上海银行”,查询到此银行关联多少张卡,并且查询其中一个银行卡的信息。

反向查询,当ForeignKey没设置related_name参数,默认是通过关联表的名称加_set去查询

  • 查询结果是QuerySet集合对象
  • count()函数统计查询个数
  • [0].card_id 下标取值,获取对应属性
>>> bank = BankName.objects.get(bank_name='上海银行')
>>> bank.city
'上海' # 反向查询,表名称_set
>>> bank.card_set.all()
<QuerySet [<Card: 62270121022100000>]> # count()函数统计
>>> bank.card_set.all().count()
1 >>> bank.card_set.all()[0].card_id
'62270121022100000'
>>>

related_name

当Card表的外键(ForeignKey)只有一个时,可以通过_set去查询到,当有多个外键时,就无法查询具体哪个外键了,这时候就需要加个related_name参数。

class CardGrade(models.Model):
'''会员等级'''
nub = models.CharField(max_length=50, verbose_name="会员等级", default="") class Meta:
verbose_name = '会员等级'
verbose_name_plural = verbose_name class BankName(models.Model):
'''银行信息'''
bank_name = models.CharField(max_length=50, verbose_name="银行名称", default="")
city = models.CharField(max_length=30, verbose_name="城市", default="")
point = models.CharField(max_length=60, verbose_name="网点", default="") class Meta:
verbose_name = '银行'
verbose_name_plural = verbose_name def __str__(self):
return self.bank_name class Card(models.Model):
'''银行卡 基本信息'''
card_id = models.CharField(max_length=30, verbose_name="卡号", default="")
card_user = models.CharField(max_length=10, verbose_name="姓名", default="")
add_time = models.DateField(auto_now=True, verbose_name="添加时间")
bank_info = models.ForeignKey(BankName, related_name='card_bank', on_delete=models.CASCADE, default="")
grade = models.ForeignKey(CardGrade, related_name='card_grade', on_delete=models.CASCADE, default="") class Meta:
verbose_name = "银行卡账户_基本信息"
verbose_name_plural = '银行卡账户' def __str__(self):
return self.card_id

related_name参数相当于给这个外键取了个别名,方便多个外键时候去识别。以下是新增数据和正向查询

当定义了related_name后”_set”这类查询就被related_name代替了,所以用”_set”会报错。

# 新增数据
>>> from hello.models import CardGrade,BankName,Card
>>> n=CardGrade.objects.create(nub='黄金会员')
>>> b=BankName.objects.create(bank_name='北京银行',city='北京')
>>> c=Card.objects.create(card_id='666555000111',card_user='杨过', bank_info=b,
grade=n) # 正向查询
>>> c.grade.nub
'黄金会员' >>> c.bank_info.city
'北京'
>>>

反向查询需要用到related_name参数,如下

# CardGrade表查Card表
>>> nnn=CardGrade.objects.get(nub='黄金会员')
>>> nnn.card_grade.all()
<QuerySet [<Card: 666555000111>]>
>>> nnn.card_grade.all()[0].card_id
'666555000111' # BankName表查Card表
>>> bbb=BankName.objects.get(bank_name='上海银行')
>>> bbb.card_bank.all()
<QuerySet [<Card: 62270121022100000>]>
>>> bbb.card_bank.all()[0].card_id
'62270121022100000'
>>>

python测试开发django-37.外键(ForeignKey)查询的更多相关文章

  1. django开发中关于外键设置

    django开发中关于外键设置 我们建模型的时候会用到ForeignKey 而由于外键的约数会导致一些保存 所有我们ctrl+左键进入源码 源码 def __init__(self, to, on_d ...

  2. 《Python测试开发技术栈—巴哥职场进化记》—前言

    写在前面 今年从4月份开始写一本讲Python测试开发技术栈的书,主要有两个目的,第一是将自己掌握的一些内容分享给大家,第二是希望自己能系统的梳理和学习Python相关的技术栈.当时我本来打算以故事体 ...

  3. 数据库开发——参照完整性——在外键中使用Delete on cascade选项

    原文:数据库开发--参照完整性--在外键中使用Delete on cascade选项 原文: http://www.mssqltips.com/sqlservertip/2743/using-dele ...

  4. pythonのsqlalchemy外键关联查询

    #!/usr/bin/env python import sqlalchemy from sqlalchemy import create_engine from sqlalchemy.ext.dec ...

  5. python测试开发django-36.一对一(OneToOneField)关系查询

    前言 前面一篇在xadmin后台一个页面显示2个关联表(OneToOneField)的字段,使用inlines内联显示.本篇继续学习一对一(OneToOneField)关系的查询. 上一篇list_d ...

  6. python测试开发django-16.JsonResponse返回中文编码问题

    前言 django查询到的结果,用JsonResponse返回在页面上显示类似于\u4e2d\u6587 ,注意这个不叫乱码,这个是unicode编码,python3默认返回的编码 遇到问题 接着前面 ...

  7. python测试开发django-15.查询结果转json(serializers)

    前言 django查询数据库返回的是可迭代的queryset序列,如果不太习惯这种数据的话,可以用serializers方法转成json数据,更直观 返回json数据,需要用到JsonResponse ...

  8. 2019第一期《python测试开发》课程,10月13号开学

    2019第一期<python测试开发>课程,10月13号开学! 主讲老师:上海-悠悠 上课方式:QQ群视频在线教学,方便交流 本期上课时间:10月13号-12月8号,每周六.周日晚上20: ...

  9. python测试开发django-rest-framework-63.基于函数的视图(@api_view())

    前言 上一篇讲了基于类的视图,在REST framework中,你也可以使用常规的基于函数的视图.它提供了一组简单的装饰器,用来包装你的视图函数, 以确保视图函数会收到Request(而不是Djang ...

  10. python测试开发django-197.django-celery-beat 定时任务

    前言 django-celery-beat 可以支持定时任务,把定时任务写到数据库. 接着前面这篇写python测试开发django-196.python3.8+django2+celery5.2.7 ...

随机推荐

  1. 发布构件到Maven中央仓库

    一.注册jira账号 访问如下网址: https://issues.sonatype.org/secure/Signup.jspa 记住邮箱,用户名,密码以备以后使用,一定牢记. 二.创建一个issu ...

  2. C#控制台程序输出彩色文字

    /* * 由SharpDevelop创建. * 用户: 从前的我 * 日期: 2012-06-03 * 时间: 21:30 * * 要改变这种模板请点击 工具|选项|代码编写|编辑标准头文件 */ u ...

  3. ***PHP 遍历数组的方法foreach

    foreach  http://php.net/manual/zh/control-structures.foreach.php (PHP 4, PHP 5) foreach 语法结构提供了遍历数组的 ...

  4. lrzsz安装

    当服务器没有安装FTP等工具上传文件时,可以通过rz上传文件,sz    文件名  进行下载文件,默认下载路径为: C:\Users\用户\Downloads,安装如下: yum install lr ...

  5. bzoj 1178 [Apio2009]CONVENTION会议中心

    这题好难啊! 我好菜啊! 思路:对于最多线段不相交, 我们可以按左端点sort之后,贪心取. 但是这个题要求选取的线段排序之后序号的字典序最小. 那么我们如果按序号贪心地从大往小往里放, 那么对于第k ...

  6. python 包详解

    包 包是一种管理 Python 模块命名空间的形式,采用"点模块名称". 比如一个模块的名称是 A.B, 那么他表示一个包 A中的子模块 B . 就好像使用模块的时候,你不用担心不 ...

  7. 【noip模拟赛3】编码

    描述 Alice和Bob之间要进行秘密通信,他们正在讨论如何对信息进行加密: Alice:“不如采用一种很简单的加密方式:’A’替换成1,’B’替换成2,„„,’Z’替换成26.” Bob:“这种加密 ...

  8. 少走弯路,一个老程序猿谈PHP职业发展规划

    PHP是一个使用者非常多的开发语言,但在每个领域里的开发侧重点有所不同互联网方面,在稳定的基础上,更注重性能.高并发,高负载的处理. PHP职业发展规划一般有三条路线,一条技能专精发展路线.另两条,是 ...

  9. gson 生成json有\u003d异常字符处理

    只需将Gson的初始化修改为 Gson gson = new GsonBuilder().disableHtmlEscaping().create(); 连接 http://blog.csdn.net ...

  10. codevs 2804 最大最小数质因数

    题目描述 Description 先输入n,n<=20;再依次输入n个不同的数,每个数<=1000000;找出最大数和最小数,并输出最大最小数的质因数,没有质因数则输出0. 输入描述 In ...