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_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‘
>>>

原文地址:https://www.cnblogs.com/mashuqi/p/11022063.html

时间: 2024-11-02 23:24:29

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

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

原文:数据库开发--参照完整性--在外键中使用Delete on cascade选项 原文: http://www.mssqltips.com/sqlservertip/2743/using-delete-cascade-option-for-foreign-keys/?utm_source=dailynewsletter&utm_medium=email&utm_content=headline&utm_campaign=2012731 参照完整性在设计数据库时需要重视,在我作为

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

前言 django查询到的结果,用JsonResponse返回在页面上显示类似于\u4e2d\u6587 ,注意这个不叫乱码,这个是unicode编码,python3默认返回的编码 遇到问题 接着前面的User表,测试数据如下 user_name psw mail yoyo 123456 [email protected] yoyo2 111111 1 yoyo5 111111 0 接着上一篇[python测试开发django-15.查询结果转json(serializers)],如果数据库里面

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

2019第一期<python测试开发>课程,10月13号开学! 主讲老师:上海-悠悠 上课方式:QQ群视频在线教学,方便交流 本期上课时间:10月13号-12月8号,每周六.周日晚上20:30-22:30 报名费:报名费2000一人(周期2个月) 联系QQ:283340479 课表如下 课程主要涉及的内容: 1.httprunner框架以及web平台做接口自动化测试 (装逼必备) 2.django平台开发 (python开发必会) 3.pytest框架结合selenium做web自动化测试 (

python测试开发之_字符串练习

编程学习是个漫长.逐渐累加复杂度.综合难度的一门工程.需要自我驱动,督促自己往前走.Python测试开发是本年度重点学习目标. 今天来一个字符串的练习题,重在思路,不断训练自己的思维. 题目:找出字符串中出现次数最多的字符,并输出其出现的位置 代码实现: #encoding=UTF-8 s = "aaabbbhhiijk" letter_count_dict={} for i in s: if letter_count_dict.has_key(i): #判断是否在字典中出现过 let

python测试开发django-41.crispy-forms设计标签式导航菜单(TabHolder)

前言 xadmin的详情页面主要是用form_layout布局,学会了完全可以不用写html代码,也能做出很好看的页面. xadmin的html页面是用的Bootstrap3框架设计的,layout布局用到的是django-crispy-forms框架,本篇详细讲下django-crispy-forms的官方文档案例 django-crispy-forms 当我们使用xadmin后台的时候,在INSTALLED_APPS里面同时添加了xadmin和crispy_forms这2个app,xadmi

Python测试开发-创建模态框及保存数据

Python测试开发-创建模态框及保存数据 原创: fin  测试开发社区  前天 什么是模态框? 模态框是指的在覆盖在父窗体上的子窗体.可用来做交互,我们经常会看到模态框用来登录.确定等等,到底是怎么实现这种弹出效果,bootstrap已经为我们提供了相应的组件. 1.界面原型 点击添加,弹出模态框, 然后输入 用户:tester, 消息:你好.如下图1所示: ▲图1 再点击保存,那么数据库就存入了以上输入的数据,查看界面的用户列表会显示tester,如下图2所示: ▲图2 2.开发过程 接下

Python自动化开发 - Django基础

本节内容 一.什么是web框架 二.MVC和MTV视图 三.Django基本命令 四.路由配置系统 五.编写视图 六.Template 七.ORM 一.什么是web框架 对于所有的web应用,本质上其实就是一个socket服务端,用户的浏览器就是一个socket客户端 #!/usr/bin/env python #coding:utf-8 import socket def handle_request(client): buf = client.recv(1024) client.send("

Django ORM - 001 - 外键表查询主表信息

开始用Django做web开发,我想大家都会遇到同样的问题,那就是如何高效快速的查询需要的数据,MVC都很简单,但是ORM折腾起来就有些费时间,我准备好好研究下Django ORM,所以会有一个系列的Blog,欢迎大家讨论拍砖. 1. 如何快速的通过外键表获取主表的信息 演示Class from django.db import models import uuid class Employee(models.Model): employee_id = models.UUIDField(prim

python测试开发django-40.模型(model)中choices使用

前言 之前一直在想页面上如果一个字段只有固定的几个选项,类似select下拉框这种,如果在表里面设置一个外键的话,是不是有点傻了,这样为了几个选项弄一张表不值得. 后来看到Django模型中的字段有个choices属性,在设计模型的时候,只需把字段参数加个choices即可,看样子是我想多了~ choices参数 如果一个字段设置了choices属性,在模版中如果我要显示这个字段,比如用户的性别,只需设置2个参数选项. 在django模版系统就会将它默认解析为一个下拉菜单,这样对于一个静态的下拉