6 單表操作
一、操作單表之前的簡單配置
1 建立表
在 Django 專案下對應的 app 目錄中的 models.py 檔案下建立模型
(1)建立模型
from django.db import models class Book(models.Model): id=models.AutoField(primary_key=True) name=models.CharField(max_length=32) price=models.DecimalField(max_digits=5,decimal_places=2) publish_date=models.DateField(default='1999-11-27') publish=models.ForeignKey(to=Publish,to_field='id')
2 在 settings 中選擇並設定需要的資料庫
DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME': '連線的資料庫名稱', 'USER': '賬戶名稱', 'PASSWORD': '賬戶密碼', 'HOST': '127.0.0.1', 'PORT': 3306, 'ATOMIC_REQUEST': True, 'OPTIONS': { "init_command": "SET storage_engine=MyISAM", } } } ''' 'NAME':要連線的資料庫,連線前需要建立好 'USER':連線資料庫的使用者名稱 'PASSWORD':連線資料庫的密碼 'HOST':連線主機,預設本機 'PORT':埠 預設3306 'ATOMIC_REQUEST': True, 設定為True統一個http請求對應的所有sql都放在一個事務中執行(要麼所有都成功,要麼所有都失敗)。 是全域性性的配置, 如果要對某個http請求放水(然後自定義事務),可以用non_atomic_requests修飾器 'OPTIONS': { "init_command": "SET storage_engine=MyISAM", } 設定建立表的儲存引擎為MyISAM,INNODB '''
1 在 mysql 連線前該資料庫必須已經建立,而上面的 sqlite 資料庫下的 db.sqlite3 則是專案自動建立 USER 和 PASSWORD 分別是資料庫的使用者名稱和密碼。設定完後,再啟動我們的Django 專案前,我們需要啟用我們的 mysql 。然後,啟動專案,會報錯:no module named SQL/">MySQLdb 。這是因為 django 預設你匯入的驅動是 MySQLdb,可是MySQLdb 對於py3有很大問題,所以我們需要的驅動是PyMySQL 所以,我們只需要找到專案名檔案下的__init__,在裡面寫入: 2 3 import pymysql 4 pymysql.install_as_MySQLdb() 注意
3 執行資料庫遷移命令即可創建出對應的表
(1)方式一:
1 初始化資料,此時還未開始建立或者更新資料 python manage.py makemigrations 2 開始建立 python manage.py migrate
(2)方式二:
進入上述圖片的操作之後,會進入一個類似於命令列的視窗,直接執行命令 (1)makemigrations 和 (2)migrate 兩條命令後即可建立表格
4 INSTALLED_APPS 確保配置檔案中寫入建立的 app 名稱
INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'app01.apps.App01Config', # app01,這個不是建議寫法 ]
注意:
MySQLclient目前只支援到python3.4,因此如果使用的更高版本的python,需要修改如下:
通過查詢路徑C:\Programs\Python\Python36-32\Lib\site-packages\Django-2.0-py3.6.egg\django\db\backends\mysql 這個路徑裡的檔案把 if version < (1, 3, 3): raise ImproperlyConfigured("mysqlclient 1.3.3 or newer is required; you have %s" % Database.__version__) 解決方法
二、單表操作
1 欄位的增加、刪除
(1)刪除:直接註釋掉欄位,執行資料庫遷移命令即可
(2)新增欄位:在 models.py 類裡直接新增欄位,直接執行資料庫遷移命令會提示輸入預設值,此時需要設定
publish = models.CharField(max_length=32,default='預設值',null=True)
注意:
1 資料庫遷移記錄都在 app01下的migrations裡 2 使用showmigrations命令可以檢視沒有執行migrate的檔案 3makemigrations是生成一個檔案,migrate是將更改提交到資料量
2 新增表記錄
(1)方式一:
# create 方法的返回值 book_obj 就是插入 book 表中的 Django 這本書籍紀錄物件 book_obj=Book.objects.create(name="Django",state=True,price=998,publish="未知出版社",pub_date="9999-99-99")
(2)方式二:
book_obj=Book(name="Django",state=True,price=998,publish="未知出版社",pub_date="9999-99-99") book_obj.save()
3 查詢表記錄的常用 API
(1)all(): 查詢所有結果 (2)filter(**kwargs): 它包含了與所給篩選條件相匹配的物件 (3)get(**kwargs): 返回與所給篩選條件相匹配的物件,返回結果有且只有一個,如果符合篩選條件的物件超過一個或者沒有都會丟擲錯誤。 (4)exclude(**kwargs): 它包含了與所給篩選條件不匹配的物件 (5)order_by(*field): 對查詢結果排序,預設是從大到小排序;字串前加 - 號('-id'),表示從小到大排序 (6)reverse(): 對查詢結果反向排序 (7)count(): 返回資料庫中匹配查詢(QuerySet)的物件數量。 (8)first(): 返回第一條記錄 (9)last(): 返回最後一條記錄 (10) exists(): 如果QuerySet包含資料,就返回True,否則返回False (11) values(*field): 返回一個ValueQuerySet——一個特殊的QuerySet,執行後得到的並不是一系列 model 的例項化物件,而是一個可迭代的字典序列 (12) values_list(*field): 它與values()非常相似,它返回的是一個元組序列,values返回的是一個字典序列 (13) distinct(): 從返回結果中剔除重複紀錄
1 book = Book.objects.all().gei(id="2")# get 只能用來查詢返回一條資料的情況,記錄過多或者過少都會產生報錯 2 book_dic = Book.objects.all().values('name','price')# 返回一個類似字典的 QuerySet 物件,經過 first() 處理之後就不是物件了,可以通過迴圈來取值 3 book_tuple = Book.objects.all().values_list()# 返回一個類似元組的 QruerySet 物件,可迴圈取值 4 reverse()# 將查詢結果反向排序,但是必須在 order_by() 之後使用才可以生效 5 :one: Book.objects.all().order_by('price','publish_date').reverse() 6 :two: Book.objects.all().order_by('-price','publish_date') 7 :one: 和 :two: 結果是相同的 Notice
4 雙下劃線的模糊查詢
1 Book.objects.filter(price__in=[100,200,300]) 2 Book.objects.filter(price__gt=100)# 大於100 3 Book.objects.filter(price__lt=100) 4 Book.objects.filter(price__gte=100)# 大於等於100 5 Book.objects.filter(price__lte=100) 6 Book.objects.filter(price__range=[100,200])# 在 100 至 200 之間,包括首尾 7 Book.objects.filter(name__contains="Django") 8 Book.objects.filter(name__icontains="Django")# 忽略大小寫,由於版本原因,結果可能不一樣 9 Book.objects.filter(name__startswith="D") 10 Book.objects.filter(publish_date__year=9999)# 出版日期的年份,對應的還有月份日期等
5 刪除記錄
:one: Book.objects.filter(name="Django").first().delete() # 注意是沒有返回值的 :two: QuerySet.delete() :one: 和 :two: 的結果是一樣的 (1,{'app01.Book':1})# 各個引數的說明 第一個 1 是:總體影響的行數 app01.Book:哪個表的記錄 第二個 1 是:影響表的記錄 delete() 方法是 QuerySet 上的方法,但並不適用於 Manager 本身。這是一種保護機制,是為了避免意外地呼叫 Book.objects.delete() 方法導致 所有的 記錄被誤刪除。如果你確認要刪除所有的物件,那麼你必須顯式地呼叫: Book.objects.all().delete()
若不想級聯刪除,可以設定為: pubHouse = models.ForeignKey(to='Publisher', on_delete=models.SET_NULL, blank=True, null=True) 級聯刪除引數設定
在 Django 刪除物件時,會模仿 SQL 約束 ON DELETE CASCADE 的行為,換句話說,刪除一個物件時也會刪除與它相關聯的外來鍵物件。例如: b = Blog.objects.get(pk=1) # This will delete the Blog and all of its Entry objects. b.delete() Notice
6 更新表記錄
update() 方法對於任何結果集(QuerySet)均有效,Manage 物件不可呼叫,意味著你可以同時更新多條記錄update()方法會返回一個整型數值,表示受影響的記錄條數。
Book.objects.filter(name__startswith="D").update(price=999)
三、在 Python 指令碼中呼叫 Django 環境(瞭解)
import os if __name__ == '__main__': os.environ.setdefault("DJANGO_SETTINGS_MODULE", "Django名稱.settings") import django django.setup() from app01 import models books = models.Book.objects.all() print(books)
注意:
Django 名稱可以在 manage.py 中檢視或者核對
四、Django 中列印 SQL 語句
方式一: LOGGING = { 'version': 1, 'disable_existing_loggers': False, 'handlers': { 'console':{ 'level':'DEBUG', 'class':'logging.StreamHandler', }, }, 'loggers': { 'django.db.backends': { 'handlers': ['console'], 'propagate': True, 'level':'DEBUG', }, } } 方式二: obj = Book.objects.all().filter(pk=1) print(obj.query)