django模型操作

一碗湯麵發表於2020-11-23

配置
1.建立 urls.py檔案 (user應用裡)

2.在 主路由配置
path(’’,include(‘user.urls’))
#導包路徑 sys.path 必須有個 apps目錄 作為查詢包的路徑

3.settings裡
import sys # python直譯器系統
sys.path.insert(0,os.path.join(BASR_DIR,‘apps’))

#配置應用
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'user.apps.UserConfig',

]

# 配置資料庫
DATABASES = {
'default': {
    'ENGINE': 'django.db.backends.mysql',
    'NAME': '資料庫名',
    'HOST': '127.0.0.1',
    'PORT': 3306,
    'USER': 'root',
    'PASSWORD': '密碼'
}

}

# 指預設的使用者模型  django特有的模型路徑
# '應用名.模型名'
# 1.系統路徑 檔案 資料夾
# 2.python直譯器系統導包路徑
# 3.django系統的模型路徑
AUTH_USER_MODEL = 'user.User'

Django路徑問題

檔案路徑(os.path) windows作業系統的路徑
導包路徑(sys.path) python直譯器系統 查詢包的路徑
模組路徑(user.User) django特有的模型路徑
模型路徑

外來鍵的順序調換 會報錯

=報錯==

1 直接寫模型名

class Pinglun(models.Model):
content = models.CharField()
user = models.ForeignKey(User)

class User(AbstractUser):
# 冗餘設計
phone = models.CharField(‘手機號’, max_length=24)

class Meta:
    db_table = 'tb_user'

=不報錯==

2 使用模型路徑(應用名.模型名)

class Pinglun(models.Model):
    content = models.CharField()
    user = models.ForeignKey('user.User')  

class User(AbstractUser):
    # 冗餘設計
    phone = models.CharField('手機號', max_length=24)

    class Meta:
        db_table = 'tb_user'

demo

進入目錄: ls syl
進入目錄: cd apps
#因為 manage.py 檔案 是在 syl目錄下
建立應用: python …/manage.py startapp demo

#配置應用
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'user.apps.UserConfig',
'demo_app.apps.DemoAppConfig',

]

from django.db import models

#定義圖書模型類BookInfo
class BookInfo(models.Model):
btitle = models.CharField(max_length=20, verbose_name=‘名稱’)
bpub_date = models.DateField(verbose_name=‘釋出日期’)
bread = models.IntegerField(default=0, verbose_name=‘閱讀量’)
bcomment = models.IntegerField(default=0, verbose_name=‘評論量’)
is_delete = models.BooleanField(default=False, verbose_name=‘邏輯刪除’)

class Meta:
    db_table = 'tb_books'  # 指明資料庫表名
    verbose_name = '圖書'  # 在admin站點中顯示的名稱
    verbose_name_plural = verbose_name  # 顯示的複數名稱

def __str__(self):
    """定義每個資料物件的顯示資訊"""
    return self.btitle

#定義英雄模型類HeroInfo
class HeroInfo(models.Model):
GENDER_CHOICES = (
(0, ‘female’),
(1, ‘male’)
)
hname = models.CharField(max_length=20, verbose_name=‘名稱’)
hgender = models.SmallIntegerField(choices=GENDER_CHOICES, default=0, verbose_name=‘性別’)
hcomment = models.CharField(max_length=200, null=True, verbose_name=‘描述資訊’)
hbook = models.ForeignKey(BookInfo, on_delete=models.CASCADE, verbose_name=‘圖書’) # 外來鍵
is_delete = models.BooleanField(default=False, verbose_name=‘邏輯刪除’)

class Meta:
    db_table = 'tb_heros'
    verbose_name = '英雄'
    verbose_name_plural = verbose_name

def __str__(self):
    return self.hname

查詢操作

‘’’
get 獲取一個
all filter exclude 獲取多個
‘’’

錯誤操作==
BookInfo.objects.get(id=5)

該條資訊不存在 報錯

demo_app.models.DoesNotExist: BookInfo matching query does not exist.

BookInfo.objects.get(bread=0)

有多個結果的時候 報錯

demo_app.models.MultipleObjectsReturned: get() returned more than one BookInfo – it returned 2!

可以這樣使用 get方法 不會報錯

try:
book=BookInfo.objects.get(id=0)
# 有且只有一個結果的時候 才會成功
except:
book=None

正確操作==

  1. 獲取滿足條件的 (filter)
    bobooks=BookInfo.objects.filter(id=1)
    book=books.first()
    print(book) # 射鵰英雄傳

  2. books=BookInfo.objects.filter(id=0)
    print(books) #<QuerySet []>
    book=books.first() # books.last()
    print(book) # None

  3. 不滿足條件的 (exclude)
    books=BookInfo.objects.exclude(id=1)
    print(books)
    <QuerySet [<BookInfo: 天龍八部>, <BookInfo: 笑傲江湖>, <BookInfo: 雪山飛狐>, <BookInfo: 新書>, <BookInfo: 新書3>]>

  4. 獲取全部資料 (all)
    books=BookInfo.objects.all() # 所有的
    print(books.first()) # 射鵰英雄傳

  5. filter方法

    1. #查詢書名包含’傳’的圖書。
      book=BookInfo.objects.filter(btitle__contains=‘傳’)
      print(book) # <QuerySet [<BookInfo: 射鵰英雄傳>]>

    2. #查詢書名以 '天’開頭的圖書
      #查詢書名以 '狐’結尾的圖書
      book=BookInfo.objects.filter(btitle__startswith=‘天’)
      print(book) # <QuerySet [<BookInfo: 天龍八部>]>
      books=BookInfo.objects.filter(btitle__endswith=‘狐’)
      print(books) # <QuerySet [<BookInfo: 雪山飛狐>]>

    3. 給英雄隨便加一條 hcomment 為空的資訊 不是字串

      給英雄隨便加一條 hcomment 為空字串的資訊

      hero=HeroInfo.objects.filter(hcomment=’’)
      for i in hero:
      print(i.id) # 18

      hero=HeroInfo.objects.filter(hcomment=None)
      hero=HeroInfo.objects.filter(hcomment__isnull=True)
      for i in hero:
      print(i.id) # 19

    4. book=BookInfo.objects.filter(bread__in=[12,36,20])
      book=BookInfo.objects.filter(bread__range=[12,50])
      book=BookInfo.objects.filter(bread__in=[i for i in range(12,50)])
      print(book) #
      <QuerySet [<BookInfo: 射鵰英雄傳>, <BookInfo: 天龍八部>, <BookInfo: 笑傲江湖>]>

    5. books=BookInfo.objects.filter(bpub_date__year__gt=‘1990’)
      books=BookInfo.objects.filter(bpub_date__month__gt=‘10’)
      books=BookInfo.objects.filter(bpub_date__day__gt=‘20’)

      每週的第一天是週日

      books=BookInfo.objects.filter(bpub_date__week_day=‘1’)

      year、month、day、week_day、hour、minute、second

      bpub_date:年月日 bpub_date__year 年 __gt 大於

      print(books)

    6. 例:查詢閱讀量大於等於評論量的圖書。

      from django.db.models import F

      一個物件的兩個欄位之間的進行比較 F(‘另外一個欄位名’)

      book=BookInfo.objects.exclude(bread=0).filter(bread__gte=F(‘bcomment’))
      print(book)
      books=BookInfo.objects.exclude(bread=0).filter(bread__gte=F(‘bcomment’)*2)
      print(books)

      <QuerySet [<BookInfo: 雪山飛狐>]>

    7. Q物件

      多個過濾器逐個呼叫表示邏輯與關係,同sql語句中where部分的and關鍵字。

      例:查詢閱讀量大於20,並且編號小於3的圖書。

      book=BookInfo.objects.filter(bread__gt=20,id__lt=3)
      print(book)

      <QuerySet [<BookInfo: 天龍八部>]>

      例:查詢閱讀量大於20,或編號小於3的圖書。

      book=BookInfo.objects.filter(Q(bread__gt=20)|Q(id__lt=3))
      print(book)
      #<QuerySet [<BookInfo: 射鵰英雄傳>, <BookInfo: 天龍八部>, <BookInfo: 雪山飛狐>]>

    8.  # 例:查詢圖書的總閱讀量。
       from django.db.models import Sum,Avg,Count,Min,Max
      
       books=BookInfo.objects.all()
       # 從資料庫中取了所有的書的資料 (取回的資料量大)
       bread_count=0
       for i in books:
           bread_count+=i.bread # 累加 需要遍歷
       print(bread_count) # 126
      
      
       book=BookInfo.objects.aggregate(Sum('bread'),
                                       Avg('bread'),
                                       Count('bread'),
                                       Min('bread'),
                                       Max('bread'))
       # 資料庫給累加的 快速高效
       print(book)
      
       # 聚合函式 Avg平均 Count 數量 Max 最大 Min最小 Sum 求和
       {'bread__sum': 126, 'bread__avg': 21.0,
       'bread__count': 6, 'bread__min': 0, 'bread__max': 58}
      
    9. books=BookInfo.objects.all().order_by('bread')
      print(books)
      books=BookInfo.objects.all().order_by('-bread')
      print(books)
      
    10. 關聯查詢
      # 關聯查詢 兩方 從一方查另外一方 關聯查詢
      book_1=BookInfo.objects.get(id=1)

      hero=HeroInfo.objects.get(id=1)
      book=hero.hbook # 是英雄所在書籍的物件
      print(book.id)
      print(book.btitle)
      # 所屬關係 英雄是屬於書的 外來鍵要在英雄裡面寫
      # 通過英雄查書 說書是屬於作者的
      兩個表的關係 不是一個關係的時候 
      # 獲取圖書的英雄
      book=BookInfo.objects.get(id=1)
      # 管理器 管理外來鍵關係
      heros=book.heroinfo_set.all() # 集合
      print(heros)	
      
      
      related_name='' 重寫 預設多出來的欄位的名稱
      # 被指向模型 預設會多出來一個欄位 heroinfo_set
      '''
       class Teacher():
       	name=''
      
      class Person():
          name=''
          friend=fk(Teacher,related_name='friends')
          teacher=fk(Teacher,related_name='students')
       '''
      
    11.關聯 過濾查詢
        # 過濾查詢 條件是關聯模型的屬性
         heros=HeroInfo.objects.filter(hbook__btitle__contains='傳')
         print(heros)
         books=BookInfo.objects.filter(heroinfo__hname__startswith='郭')
         print(books)
         books=BookInfo.objects.filter(heroinfo__hcomment__contains='掌')
         print(books.distinct()) # 模型集的去重方法
    

相關文章