模型層之單表操做

ORM簡介

對象關係映射(Object Relational Mapping,簡稱 ORM)模式是一種爲了解決面向對象與關係數據庫存在的互不匹配的現象的技術。簡單的說,ORM 是經過使用描述對象和數據庫之間映射的元數據,將程序中的對象自動持久化到關係數據庫中,它實現了數據模型與數據庫的解耦,即數據模型的設計不須要依賴於特定的數據庫,經過簡單的配置就能夠輕鬆更換數據庫,這極大的減輕了開發人員的工做量,不須要面對因數據庫變動而致使的無效勞動。python

sql中的表                                                      
CREATE TABLE employee(                                     
     id INT PRIMARY KEY auto_increment ,                    
     name VARCHAR (20),                                      
     gender BIT default 1,                                  
     birthday DATA ,                                         
     department VARCHAR (20),                                
     salary DECIMAL (8,2) unsigned,                          
 );                                               

添加一條表紀錄:                                                          
INSERT employee(name, gender, birthday, salary, department)
    VALUES("alex", 1, "1985-12-12", 8000, "保潔部");               

查詢一條表紀錄:                                                           
SELECT * FROM employee WHERE age=24;                               

更新一條表紀錄:                                                           
UPDATE employee SET birthday="1989-10-24" WHERE id=1;              

刪除一條表紀錄:                                                          
DELETE FROM employee WHERE name="alex"
# python的類
class Employee(models.Model):
     id = models.AutoField(primary_key=True)
     name = models.CharField(max_length=32)
     gender = models.BooleanField()
     birthday = models.DateField()
     department = models.CharField(max_length=32)
     salary = models.DecimalField(max_digits=8,decimal_places=2)

# 添加一條表紀錄:
emp=Employee(name="alex",gender=True,birthday="1985-12-12",epartment="保潔部")
emp.save()

# 查詢一條表紀錄:
Employee.objects.filter(age=24)

# 更新一條表紀錄:
Employee.objects.filter(id=1).update(birthday="1989-10-24")

# 刪除一條表紀錄:
Employee.objects.filter(name="alex").delete()
類    ——  表
類屬性 ——  表字段
類對象 ——  表記錄

單表操做

建立表

建立模型

建立名爲 app01 的 app,在 app01 下的 models.py 中建立模型mysql

class Book(models.Model):
    nid = models.AutoField(primary_key=True)
    title = models.CharField(max_length=20)
    price = models.DecimalField(max_digits=5, decimal_places=2)
    pub_data = models.DateTimeField()
    publish = models.CharField(max_length=32)

字段和參數

每一個字段有一些特有的參數,例如,CharField 須要 max_length 參數來指定數據庫字段的大小。還有一些適用於全部字段的通用參數。 這些參數在文檔中有詳細定義,這裏只簡單介紹一些最經常使用的:git

AutoField
    - int自增列,必須填入參數 primary_key=True

BooleanField
    - 布爾值類型

CharField
    - 字符類型,必須提供 max_length 參數,max_length表示字符長度
    
TextField
    - 文本類型
    
EmailField
    - Django Admin 以及 ModelForm 中提供驗證機制
    
ImageField
    - 字符串,路徑保存在數據庫,文件上傳到指定目錄
    - 參數:
        upload_to = ""      上傳文件的保存路徑
        storage = None      存儲組件,默認django.core.files.storage.FileSystemStorage
        width_field=None    上傳圖片的高度保存的數據庫字段名(字符串)
        height_field=None   上傳圖片的寬度保存的數據庫字段名(字符串)
        
DateTimeField
    - 日期+時間格式 YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ]
    
DateField
    - 日期格式      YYYY-MM-DD
    
TimeField
    - 時間格式      HH:MM[:ss[.uuuuuu]]
    
FloatField
    - 浮點型
    
DecimalField
    - 10進制小數
    - 參數:
        max_digits          小數總長度
        decimal_places      小數位長度
一、null 
若是爲True,Django 將用NULL 來在數據庫中存儲空值。 默認值是 False.
 
二、blank
若是爲True,該字段容許不填。默認爲False。
要注意,這與 null 不一樣。null純粹是數據庫範疇的,而 blank 是數據驗證範疇的。
若是一個字段的blank=True,表單的驗證將容許該字段是空值。若是字段的blank=False,該字段就是必填的。
 
三、default
字段的默認值。能夠是一個值或者可調用對象。若是可調用 ,每有新對象被建立它都會被調用。
 
四、primary_key
若是爲True,那麼這個字段就是模型的主鍵。若是沒有指定任何一個字段的 primary_key=True,
Django就會自動添加一個 IntegerField 字段作爲主鍵,
因此除非想覆蓋默認的主鍵行爲,不然不必設置任何一個字段的primary_key=True。
 
五、unique
若是該值設置爲 True, 這個數據字段的值在整張表中必須是惟一的
 
六、choices
由二元組組成的一個可迭代對象(例如,列表或元組),用來給字段提供選擇項。 若是設置了choices ,默認的表單將是一個選擇框而不是標準的文本框,並且這個選擇框的選項就是choices中的選項。

settings 配置

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'bms',              # 要鏈接的數據庫,鏈接前須要建立好
        'USER': 'root',             # 鏈接數據庫的用戶名
        'PASSWORD': '000000',       # 鏈接數據庫的密碼
        'HOST': '127.0.0.1',        # 鏈接主機,默認本級
        'PORT': 3306,               # 端口 默認3306
    }
}

注意一:NAME 即數據庫的名字,在 mysql 鏈接前該數據庫必須已經建立,而上面的 sqlite 數據庫下的 db.sqlite3 則是項目自動建立。 USER 和 PASSWORD 分別是數據庫的用戶名和密碼。設置完後,在啓動 Django 項目前,須要激活 mysql。而後啓動項目,會報錯:no module named MySQLdb 。這是由於 django 默認導入的驅動是 MySQLdb,但是 MySQLdb 對於 Python3 有很大問題,所以使用驅動 PyMySQL。因此,須要找到項目名文件下的 __init__.py ,在裏面寫入:sql

import pymysql
pymysql.install_as_MySQLdb()

注意二:確保配置文件中的 INSTALLED_APPS 中寫入了建立的 app 名稱數據庫

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'app01',
]

數據庫遷移

django 會把 settings 中的 INSTALLED_APPS 的每個應用中 models 對應的類建立成數據庫中的表,在當前環境的項目目錄下執行兩個命令:django

python manage.py makemigrations
python manage.py migrate

添加表記錄

方式一

# create方法的返回值book_obj就是插入Book表中的這本書的記錄對象
book_obj = Book.objects.create(title="圖解HTTP", price=49, pub_date="2014-11-12", publish="人民郵電出版社")

方式二

book_obj = Book(title="圖解HTTP", price=49, pub_date="2014-11-12", publish="人民郵電出版社")
book_obj.save()

查詢表記錄

爲了方便查詢,在此以前已添加多條記錄api

查詢API

all()                   查詢全部結果
  
filter(**kwargs)        它包含了與所給篩選條件相匹配的對象
  
get(**kwargs)           返回與所給篩選條件相匹配的對象,返回結果有且只有一個,若是符合篩選條件的對象超過一個或者沒有都會拋出錯誤。
  
exclude(**kwargs)       它包含了與所給篩選條件不匹配的對象
 
order_by(*field)        對查詢結果排序
  
reverse()               對查詢結果反向排序
  
count()                 返回數據庫中匹配查詢(QuerySet)的對象數量。
    
first()                 返回第一條記錄
  
last()                  返回最後一條記錄
  
exists()                若是QuerySet包含數據,就返回True,不然返回False
 
values(*field)          返回一個ValueQuerySet,一個特殊的QuerySet,運行後獲得的並非一系列model的實例化對象,而是一個可迭代的字典序列
        
values_list(*field)     它與values()很是類似,它返回的是一個元組序列,values返回的是一個字典序列
 
distinct()              從返回結果中剔除重複紀錄
def addbook(request):

    # 添加表記錄
    # book = Book.objects.create(title="圖解HTTP", price=49, pub_date="2014-11-12", publish="人民郵電出版社")

    # 查詢表記錄
    # 一、all:返回一個QuerySet對象
    # book_list = Book.objects.all()
    # print(book_list[0].title)       # 圖解HTTP
    # print(book_list)                # <QuerySet [<Book: Book object>]>

    # 查詢全部書籍名
    # for obj in book_list:
    #     print(obj.title)

    # 二、first/last:調用者是QuerySet對象,返回值是對象
    # book = Book.objects.all().first()
    # book_2 = Book.objects.all().last()
    # print(book)
    # print(book2)

    # 三、filter:返回值是QuerySet對象(至關於where語句),能夠加多個過濾條件
    # book = Book.objects.filter(title='圖解TCP/IP').first()
    # print(book)

    # 四、get:有且只有一個查詢結果纔有意義,返回值是一個對象
    # 沒有這個查詢結果會報錯
    # book = Book.objects.get(title='Python源碼剖析')
    # print(book)

    # 五、exclude:除了查詢以外的,返回值也是QuerySet
    # ret = Book.objects.exclude(title='圖解HTTP')
    # print(ret)

    # 六、order_by:默認升序,加個-就是降序。能夠有多個過濾條件,調用者是QuerySet,返回值也是QuerySet
    # book_list = Book.objects.all().order_by('nid')
    # book_list_2 = Book.objects.all().order_by('-id', 'price')
    # print(book_list)

    # 七、count:調用者是QuerySet,返回值是int
    # ret = Book.objects.all().count()
    # print(ret)

    # 八、exists:判斷是是否有值,不能傳參數
    # ret = Book.objects.all().exists()
    # print(ret)

    # 九、values:調用是QuerySet,返回值也是QuerySet
    # ret = Book.objects.values('price')
    # print(ret)

    # 十、value_list:調用是QuerySet,返回值也是QuerySet
    # ret = Book.objects.all().values_list('price', 'title')
    # print(ret)

    # 十一、distinct:調用是QuerySet,返回值也是QuerySet
    # ret = Book.objects.all().values('title').distinct()
    # print(ret)

    return HttpResponse('OK')

雙下劃線模糊查詢

# 查詢價格大於50的書的名字
# ret = Book.objects.filter(price__gt=50).values('title')
# print(ret)

# 查詢大於40小於50的書
# ret = Book.objects.filter(price__gt=40, price__lt=50)
# print(ret)

# 查詢以「圖解」開頭的書的名字
# ret = Book.objects.filter(title__startswith='圖解').values('title')
# print(ret)

# 查詢包含‘Python’的書
# ret = Book.objects.filter(title__contains='Python').values('title')
# print(ret)
# icontains  不區分大小寫

# 價格在69,89,100中的
# ret = Book.objects.filter(price__in=[69, 89, 100]).values('title')
# print(ret)

# 出版日期在2016年的
# ret = Book.objects.filter(pub_date__year=2016)
# print(ret)

刪除表記錄

刪除方法就是 delete,它運行時當即刪除對象而不返回任何值。例如:session

model_obj.delete()

也能夠一次性刪除多個對象。每一個 QuerySet 都有一個 delete() 方法,它一次性刪除 QuerySet 中全部的對象。例如,下面的代碼將刪除 pub_date 是 2005 年的 Entry 對象:app

Entry.objects.filter(pub_date__year=2005).delete()

在 Django 刪除對象時,會模仿 SQL 約束 ON DELETE CASCADE 的行爲,換句話說,刪除一個對象時也會刪除與它相關聯的外鍵對象。例如:設計

b = Blog.objects.get(pk=1)
# This will delete the Blog and all of its Entry objects.
b.delete()

要注意的是: delete() 方法是 QuerySet 上的方法,但並不適用於 Manager 自己。這是一種保護機制,是爲了不意外地調用 Entry.objects.delete() 方法致使全部的記錄被誤刪除。若是確認要刪除全部的對象,那麼必須顯式地調用:

Entry.objects.all().delete() 

若是不想級聯刪除,能夠設置爲:

pubHouse = models.ForeignKey(to='Publisher', on_delete=models.SET_NULL, blank=True, null=True)

修改表記錄

Book.objects.filter(title__startswith="Py").update(price=120)

此外,update 方法對於任何結果集(QuerySet)均有效,這意味着能夠同時更新多條記錄 update 方法會返回一個整型數值,表示受影響的記錄條數。

在Python腳本中調用Django環境

import os
if __name__ == '__main__':
    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "untitled15.settings")
    import django
    django.setup()

    from app01 import models

    books = models.Book.objects.all()
    print(books)

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',
        },
    }
}
相關文章
相關標籤/搜索