python测试开发django-37.外键(ForeignKey)查询

python

前面在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)查询 的全部内容, 来源链接: utcz.com/z/389458.html

回到顶部