1. 程式人生 > >Django-Models-多表查詢

Django-Models-多表查詢

Django-Models-多表查詢

  1. 表關係

    • 一對多:models.ForeignKey(其他表)
    • 多對多:models.ManyToManyField(其他表)
    • 一對一:models.OneToOneField(其他表)
  2. 一對多關係(從表為userinfo和主表usertype)

    1. 設定外來鍵

           user_type=models.ForeignKey(to="usertype",to_field="id",default=1,on_delete= models.CASCADE)
      

      此時、主表為usertype,從表為userinfo.注意在資料庫中表明為“模組名_類名的小寫形勢”。加入模組名為userinfo,這兩個表名分貝為“user_usertype”和"user_userinfo".
      在從表中會產生一個新的欄位:user_type_id.但注意user_type代表的是主表usertpye物件。

      注意加上on_delete= models.CASCADE

      • models.CASCADE,刪除關聯資料,與之關聯也刪除

      • models.DO_NOTHING,刪除關聯資料,引發錯誤IntegrityError

      • models.PROTECT,刪除關聯資料,引發錯誤ProtectedError

      • models.SET_NULL,刪除關聯資料,與之關聯的值設定為null(前提FK欄位需要設定為可空)

      • models.SET_DEFAULT,刪除關聯資料,與之關聯的值設定為預設值(前提FK欄位需要設定預設值)

    2. 查詢資料資料時user_type就是主表的物件

      ####查詢資料

      1. 正向查詢(由從表到主表的查詢)

         users=models.userinfo.objects.all()
        
         for user in users:
             print(user.user_type.id) #等價於print(user.user_type_id)
             print(user.user_type.name)
        

        如果單純想拿到user_type的值可以這麼樣:

         users=models.userinfo.objects.all().values('telephone','password','user_type')
        

        請注意這是資料的型別為字典型別的queryset

      2. 逆向查詢(由主表到從表的查詢)

         #get得到的直接是一個物件,不過get只能檢視有一條記錄的
         #查詢型別為vip的物件
         t = models.usertype.objects.get(name='vip')
         
         #查詢型別為vip的所有使用者
         
         users=t.userinfo_set.all()
         #users=t.userinfo_set.all().values()
         #users=t.userinfo_set.all().values("id","telephone")
        

        注意userinfo_set為系統提供的集合表示方式

    3. 比較厲害的雙下劃線

       users=models.userinfo.objects.all().values('telephone','user_type__name')# __name
      

      s資料型別

       {"telephone": "root", "password": "999", "user_type__name": "\u666e\u901a\u7528\u6237"}, {"telephone": "admin", "password": "123", "user_type__name": "VIP\u7528\u6237"}
      

    新增資料

    1. 方式一,先主表然後從表(不推薦)

      例如:
      try:
      t = {
      “name”: “user”
      }

           obj = models.Type.objects.create(**t)
           print(obj.id)
           
           #獲取主表id
           user = {
               "telephone": "138",
               "password": "111",
               "user_type_id":obj.id
           }
      
           obj_u=models.UserInfo.objects.create(**user)
      
    2. 方式二

      例如:增加一個vip使用者

       #1. 找出型別表中vip
       
       	obj_type =models.Type.objects.filter(name='vip')[0]
       #2. 把查出的物件直接寫入,注意user_type就是一對多連結物件: 
       # user_type=models.ForeignKey(to='Type',to_field='id',default=1,on_delete=models.CASCADE)
      
       
       	user = {
           "telephone": "139",
           "password": "222",
           "user_type":obj_type
       }
      
       obj_u=models.UserInfo.objects.create(**user)
      
  3. 多對多關係

    需要匯入包時:

     from jobapp.models import *
    

    因為setting.py已經設定

     INSTALLED_APPS = [
         'django.contrib.admin',
         'django.contrib.auth',
         'django.contrib.contenttypes',
         'django.contrib.sessions',
         'django.contrib.messages',
         'django.contrib.staticfiles',
         'position',
         'jobapp'
     
     ]
    
  4. 建立多對多關係表

     # 模擬多對多關係:使用者-投遞-職位
     class applyposition(models.Model):
         id = models.AutoField(primary_key=True)
         # 自動建立一個id列,id為主鍵、自增長
         uobj = models.ForeignKey(to=userinfo,to_field='id',on_delete=True)
         pobj = models.ForeignKey(to="position",to_field='id',on_delete=True)
         publish_time=models.DateTimeField(auto_now_add=True,null=True)
    

    當然,這樣創作好理解但是繁瑣,我們可以直接在崗位模型中加入一條語句

     from jobapp.models import *
     
     #在job表中
     apply=models.ManyToManyField(userinfo)
    
  5. 資料操作

    1. 增加資料

      這個時候要先確定一個條件,比如user01投遞了position01,那麼我們就確定了崗位:

       pos=positon.objects.get(id=1)
       
       pos.apply.add(1) #這個時候的1就是使用者id
       pos.apply.add(1,2,3) #這個時候的1,2,3就是使用者id
       pos.apply.add(*[1,2,3,4]) #這個時候的1就是使用者id
      
    2. 刪除資料

       pos.apply.remove(2)
       pos.apply.remove(1,2,3)	
       pos.apply.remove(*[1,2,3])	
       pos.apply.clear()
      
    3. 修改資料

       #關係表中崗位表是1的,只會有使用者名稱1,2,3.其他都會刪除
       pos.apply.set(1,2,3)
      
    4. 查詢資料

       pos=positon.objects.get(id=1)
       
       #此時拿到的物件集合為使用者物件集合
       pos.apply.all()
       
       #要拿到關聯表中(比如使用者表中的)其他欄位
       
       pos.apply.all().values('job_apply_password','job_apply_telephone')
      

      ==
      # 新增資料
      pp = models.position.objects.get(id=2)
      pp.apply.add(7)

       #查詢資料
       pos=models.position.objects.get(id=1)
       print(pos.name)
       print(pos.apply.all().filter(id=1))
       users=pos.apply.all()
       for u in users:
           print(u.telephone)