python测试开发django-37.外键(ForeignKey)查询
时间:2022-06-20
本文章向大家介绍python测试开发django-37.外键(ForeignKey)查询,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
前言
前面在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_djohelloworld>python manage.py shell
>>> from hello.models import Card, BankName
>>> a = BankName.objects.create(bank_name='上海银行', city='上海', point='徐家汇区')
>>> c = Card.objects.create(card_id='62270121022100000', card_user='张三', bank_info=a)
正向查询
根据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参数相当于给这个外键取了个别名,方便多个外键时候去识别。以下是新增数据和正向查询
# 新增数据
>>> 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'
>>>
- 06-图2 Saving James Bond - Easy Version
- 06-图1 列出连通集
- Bootstrap快速入门
- 常用工具(Windows版本)
- Hadoop快速入门
- Lake Counting(POJ-2386)
- Vue快速入门
- 04-树6. Huffman Codes--优先队列(堆)在哈夫曼树与哈夫曼编码上的应用
- SpringAOP实战应用
- 04-树5. File Transfer--并查集
- React快速入门
- 04-树4. Root of AVL Tree-平衡查找树AVL树的实现
- Java并发编程快速学习
- Stanford机器学习笔记-7. Machine Learning System Design
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法