Django框架学习13--一对一,一对多,多对多表的查询操作

1.一对一表的查询操作(OneToOneField)

上篇中记录了一对一表,card和cardInfo表的创建关联,使用inlines内联显示。

Django框架除了在views.py中操作models外,还可以从shell模式下进行数据库的操作。

进入shell模式,在manage.py目录下执行

python3 manage.py shell

>>> from hello.models import Card,CardDetail
>>> c = Card.objects.create(card_id='5555',card_user='hanlei')
>>> c.save()
>>> d = CardDetail.objects.create(card=c,tel='110',mail='1@qqq.com',city='上海',address='松江')
>>> d.save()

新增一个card和carddetail表数据

数据查询:1.根据c和d对象查询属性信息:

>>> c.card_id
'5555'
>>> c.card_user
'hanlei'
>>> d.city
'上海'
>>> d.address
'松江'

2.根据card查询carddetail和根据carddetail查询card信息

>>> c.carddetail.mail
'1@qqq.com'
>>> d.card.card_user
'hanlei'
>>>

另外如果想让card表界面显示carddetail信息,需要自己修改list_display列表

@admin.register(models.Card)
class ControlCard(admin.ModelAdmin):
    list_display = ["card_id", "card_user", "add_time","phone","city"]#增加phone和city两个字段

    # 在Card页面显示更多信息CardDetail
    inlines = [MoreInfo]
    #新增方法,可以在card界面显示carddetail中phone字段信息
    def phone(self, obj):
        return obj.carddetail.tel

    # 新增方法,可以在card界面显示carddetail中city字段信息
    def city(self, obj):
        return obj.carddetail.city

2.一对多表查询操作(ForignKey)

新增一条bank和cardinfo信息,可以根据card_info查询对应的bank信息,但是不能直接根据bank查询cardinfo信息

因为cardinfo中关联了info,而bank中没有关联card_info,这也是不能进行关联的,因为一个银行下可以有多个银行卡

>>>from hello.models import Bank,CardInfo
>>> b = Bank.objects.create(bank_name='招商银行',city='北京',point='海淀')
>>> b.save
<bound method Model.save of <Bank: 招商银行>>
>>> card_info =CardInfo.objects.create(card_id='88888',card_name='小强',info=b)
>>> card_info.save
<bound method Model.save of <CardInfo: 88888>>
>>> b.city
'北京'
>>> card_info.card_name
'小强'
>>> card_info.info.bank_name
'招商银行'
>>> card_info.info.city
'北京'
>>>

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

>>> b.cardinfo_set.all()[0].card_id
'88888'
>>>

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

class CardInfo(models.Model):
    '''卡信息'''
    card_id = models.CharField(max_length=30, verbose_name="卡号")
    card_name = models.CharField(max_length=10, verbose_name="姓名")
    # 增加外键,新增related_name参数related_name参数相当于给这个外键取了个别名,方便多个外键时候去识别
    info = models.ForeignKey(Bank, on_delete=models.CASCADE, verbose_name="选择银行",related_name='card_bank')

    class Meta:
        verbose_name_plural = '卡号信息'

    def __str__(self):
        return self.card_id
E:\Django_project\helloword>python3 manage.py shell
Python 3.7.0 (v3.7.0:1bf9cc5093, Jun 27 2018, 04:06:47) [MSC v.1914 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>>
>>> from hello.models import Bank,CardInfo
>>> b = Bank.objects.all()
>>> b
<QuerySet [<Bank: 中国工商银行>, <Bank: 中国农业银行>, <Bank: 招商银行>]>
>>> b[2].card_bank.all()[0].card_id
'88888'
>>>

3.多对多表查询(ManyToManyField)

多对多表的查跟一对多表的查询一致

作者表与书籍表的对应于多对多表

添加书籍表时,不能直接像如下添加

>>> from hello.models import Auther,Book
>>> a = Auther.objects.create(name='樊登',mail='aa.com',city='上海')
>>> a.save()
>>> a.save
<bound method Model.save of <Auther: 樊登>>
>>> b = Book.objects.create(book_name='看见',auth=a)
Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "C:\Python\lib\site-packages\django\db\models\manager.py", line 82, in manager_method
    return getattr(self.get_queryset(), name)(*args, **kwargs)
  File "C:\Python\lib\site-packages\django\db\models\query.py", line 420, in create
    obj = self.model(**kwargs)
  File "C:\Python\lib\site-packages\django\db\models\base.py", line 496, in __init__
    _setattr(self, prop, kwargs[prop])
  File "C:\Python\lib\site-packages\django\db\models\fields\related_descriptors.py", line 538, in __set__
    % self._get_set_deprecation_msg_params(),
TypeError: Direct assignment to the forward side of a many-to-many set is prohibited. Use auth.set() instead.

可以先添加一个不包含auth字段的book对象,然后通过book.auth.add()方法添加

>>> b = Book.objects.create(book_name='看见')
>>> b.save()
>>> b.auth.add(a)

或者知道auth对应id可以添加id

b.auth.add(1),1为a在表中的id,add方法可以添加多个id或对象,b.auth.add(1,2),b.auth.add(a1,a2),a1,a2为auther对象

查询时候,b.auth.all()返回的是一个qureyset,可遍历取出每一个Auther

通过Auther查询book时,与一对多的反向查询一致,auther.book_set.all()或根据related_name进行查询

auther.book_auth.all()

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值