前面在admin后台页面经过设置外键,能够选择下拉框的选项,本篇主要讲解关于外键(ForeignKey)的查询python
在上一篇的基础上新增一个BankName表,Card表经过外键关联到BankNameweb
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,同步数据shell
python manage.py makemigrations
python manage.py migratedjango
为了调试方便,能够使用django的shell模式,对表的数据增删改查操做,打开cmd,cd到manage.py目录ruby
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相关信息,这个相对来讲简单一点spa
>>> 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 '上海' >>>
若是想经过银行名称“上海银行”,查询到此银行关联多少张卡,而且查询其中一个银行卡的信息。
反向查询,当ForeignKey没设置related_name参数,默认是经过关联表的名称加_set去查询设计
>>> 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' >>>
当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' >>>