Django中自帶輕量級數(shù)據(jù)庫sqlite3世囊,創(chuàng)建工程時自動在工程目錄中生成一個數(shù)據(jù)庫文件db.sqlite3作為數(shù)據(jù)庫文件反粥。這個單文件數(shù)據(jù)庫可以滿足小項目數(shù)據(jù)庫的基本功能要求济炎。Django中的models是數(shù)據(jù)庫建表操作的工具澡腾,開發(fā)者無須使用復(fù)雜的SQL語句敞映,操作簡單较曼。
使用HTML的表單操作數(shù)據(jù)庫曾刪改查是常規(guī)操作,而django自帶一個比較完善的后臺管理頁面振愿,不需要自己動手寫捷犹。
模型類和自帶輕量數(shù)據(jù)庫db.sqlite3的部署[1]
建表步驟
修改INSTALLED_APPS列表
打開settings.py,找到INSTALLED_APPS冕末,這個列表會讓項目了解到自己管理著哪些應(yīng)用萍歉,數(shù)據(jù)庫數(shù)據(jù)表的創(chuàng)建也根據(jù)這些應(yīng)用中的信息來操作。
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'helloapp',
]
在官方文檔里档桃,自己的app名寫為helloapp.apps.HelloappConfig
枪孩,兩種寫法都可以。
在這個列表中要添加自己的應(yīng)用藻肄,也可以去掉不需要的預(yù)裝應(yīng)用(理論上可以去掉蔑舞,但是想用內(nèi)置的后臺管理頁面就都要保留),只有在這個列表中的應(yīng)用嘹屯,項目才會為其創(chuàng)建數(shù)據(jù)庫攻询。
編寫models.py文件
打開應(yīng)用目錄下的models.py文件,這里寫數(shù)據(jù)表名和字段名等信息抚垄,這是數(shù)據(jù)庫建表的依據(jù)蜕窿。舉例的寫法如下:
class book(models.Model):
book_name = models.CharField(max_length = 100)
belong = models.ForeignKey(Course,on_delete=models.CASCADE)
price = models.IntegerField(default='0')
unlock_code = models.CharField(max_length=16,default=str(uuid.uuid4())[-16:])
def __str__(self):
return self.book_name + ':' + self.price
以上代碼建了一個book表,有字符串呆馁、外鍵桐经、數(shù)字、隨機字符串這幾種字段浙滤,還有一個magic方法阴挣。defaul=
用于設(shè)置初始的默認(rèn)值。str(uuid.uuid4())
是Django內(nèi)置的32位隨機字符串纺腊,加上四個橫杠分隔符一共36位畔咧。
類名即數(shù)據(jù)表名茎芭,成員名即字段名,賦值是用來設(shè)定字段類型和限制條件誓沸。
執(zhí)行數(shù)據(jù)庫創(chuàng)建
把models中的代碼構(gòu)建成實際數(shù)據(jù)庫表的過程稱為“遷移”梅桩。遷移分為兩個步驟:準(zhǔn)備遷移素材(生成遷移文件.py)、更新數(shù)據(jù)庫(應(yīng)用數(shù)據(jù)庫遷移)
python manage.py makemigrations (生成遷移文件)
sudo python manage.py migrate (更新數(shù)據(jù)庫拜隧,完成遷移)
注:(1)生成的遷移文件存放在一個目錄里宿百,可以打開看,但不要手動修改它洪添。(2)在makemigrations執(zhí)行時程序會檢查代碼垦页,如果沒有新內(nèi)容系統(tǒng)就不寫新的遷移文件。但是我們有時需要強制更新遷移文件干奢,那么在makemigrations后面加上應(yīng)用名:
python manage.py makemigrations 應(yīng)用名
在shell中測試數(shù)據(jù)庫使用
在工程目錄中執(zhí)行:
python manage.py shell
from helloapp.models import book
#此命令用于查看表中數(shù)據(jù):
book.objects.all()
#第一種添加數(shù)據(jù)的方法:
i=book(book_name='life',price='10')
i.save()
book.objects.all()
#第二種添加數(shù)據(jù)的方法:
i=book()
i.book_name='life'
i.save()
book.objects.all()
到此痊焊,在數(shù)據(jù)庫中插入了兩條數(shù)據(jù)。
Django默認(rèn)提供了后臺網(wǎng)頁來可視化管理數(shù)據(jù)庫忿峻,非常方便薄啥,詳情見下一節(jié)。
數(shù)據(jù)庫基本操作:增刪改查
以下示例代碼模擬在控制臺中操作炭菌。
增
>>> from blog.models import Blog
>>> b = Blog(name='Beatles Blog', tagline='All the latest Beatles news.')
>>> b.save()
參見
save()
接受很多此處未介紹的高級選項罪佳。參考文檔save()
獲取完整細(xì)節(jié)逛漫。
- 要一步創(chuàng)建并保存一個對象黑低,使用
create()
方法:
p=Person.objects.create(first_name="Bruce", last_name="Springsteen")
如果有重復(fù)的主鍵,create()
方法會拋出異常酌毡。
- 要查詢是否有某個字段克握,如果沒有就創(chuàng)建,使用
get_or_create()
方法:
obj, newCreate = Person.objects.get_or_create(
first_name='John',
last_name='Lennon',
defaults={'birthday': date(1940, 10, 9)},
)
這個方法返回一個包含兩個內(nèi)容的元組枷踏,第一個是查詢到的或者新插入的對象菩暗,第二個表示是否是新創(chuàng)建的對象。defaults中的內(nèi)容不作為判斷是否是同一個對象的依據(jù)旭蠕,只在新創(chuàng)鍵對象時作為屬性補充停团,也就是上面的代碼等同于以下代碼的功能:
try:
obj = Person.objects.get(first_name='John', last_name='Lennon')
except Person.DoesNotExist:
obj = Person(first_name='John', last_name='Lennon', birthday=date(1940, 10, 9))
obj.save()
刪
>>> e.delete()
(1, {'weblog.Entry': 1})
e
是一條數(shù)據(jù)對象,delete()這個方法返回被刪除的對象的數(shù)量和一個包含了每個被刪除對象類型的數(shù)量的字典掏熬。
QuerySet
都有個 delete()
方法佑稠,它會刪除 QuerySet
中的所有成員:
>>> Entry.objects.filter(pub_date__year=2005).delete()
(5, {'webapp.Entry': 5})
改
>>> b.name = 'New name'
>>> b5.save()
b
是一條數(shù)據(jù)的對象, name
是其中的一個字段旗芬。
對于自增操作舌胶,當(dāng)這個數(shù)據(jù)量需要多線程互斥時,使用F表達(dá)式:
course.buy_count = F('buy_count') + 1
更新外鍵疮丛,直接把對象賦值到外鍵字段:
>>> from blog.models import Blog, Entry
>>> entry = Entry.objects.get(pk=1)
>>> cheese_blog = Blog.objects.get(name="Cheddar Talk")
>>> entry.blog = cheese_blog
>>> entry.save()
對于多對多[2]幔嫂,見模型的關(guān)聯(lián)與約束
Entry.objects.filter(pub_date__year=2007).update(headline='Everything is the same')
查
取一條單獨的數(shù)據(jù)記錄對象
>>> one_entry = Entry.objects.get(pk=1)
如果沒有滿足條件的記錄辆它,或者有多個滿足條件的記錄,get()都會報錯履恩。所以按需適當(dāng)使用try
锰茉。
獲取對象的外鍵字段返回的也是一個對象,是外鍵對應(yīng)的對象切心。
取一個數(shù)據(jù)集合
模型類有一個Manager屬性洞辣,這個屬性可以用數(shù)據(jù)庫中的數(shù)據(jù)構(gòu)建一個QuerySet,它代表數(shù)據(jù)庫中的記錄對象的一個集合昙衅。每個模型至少有一個 Manager
扬霜,默認(rèn)名稱是 objects
。直接通過模型類使用它們:
# 檢索全部對象:
>>> qs_all = Entry.objects.all()
#通過過濾器檢索指定對象而涉,這里加不加all()都可以:
>>> qs_filter = Entry.objects.filter(pub_date__year=2006)
>>> qs_filter = Entry.objects.all().filter(pub_date__year=2006)
#通過過濾器檢索不符合的對象:
>>> qs_exclude=Entry.objects.exclude(pub_date__gte=datetime.date.today())
#多重限制條件可以使用鏈?zhǔn)竭^濾器:
>>> Entry.objects.filter(
... headline__startswith='What'
... ).exclude(
... pub_date__gte=datetime.date.today()
... ).filter(
... pub_date__gte=datetime.date(2005, 1, 30)
... )
創(chuàng)建 QuerySet
并不會引發(fā)任何數(shù)據(jù)庫活動著瓶,它表示的數(shù)據(jù)集直到你 “要使用” 時才會真正操作數(shù)據(jù)庫,從數(shù)據(jù)庫中拿出數(shù)據(jù)啼县。
多對多檢索見模型的關(guān)聯(lián)與約束
QuerySet的操作:
- 排序 order_by()
Entry.objects.filter(pub_date__year=2005).order_by('-pub_date', 'headline')
上面的結(jié)果將按pub_date降序排列材原,然后按 headline升序排列。前面的負(fù)號"-pub_date"表示 降序季眷。暗含升序余蟹。要隨機排列,請使用"?"子刮,如下所示:
Entry.objects.order_by('?')
注意:order_by('?')查詢可能昂貴且緩慢威酒,具體取決于您所使用的數(shù)據(jù)庫后端。
- 切片[:]
類似列表切片的操作挺峡,例如葵孤,這將返回前 5 個對象 (LIMIT 5):
>>> Entry.objects.all()[:5]
這會返回第 6 至第 10 個對象 (OFFSET 5 LIMIT 5):
>>> Entry.objects.all()[5:10]
不支持負(fù)索引 (例如 Entry.objects.all()[-1])
高級查詢[3]
不分大小寫的匹配:
Blog.objects.get(name__iexact="beatles blog")
大小寫敏感的包含測試:
Entry.objects.get(headline__contains='Lennon')
類似的,大小寫不敏感的包含測試: icontains橱赠。以……開頭:startswith, 以……結(jié)尾:endswith尤仍。當(dāng)然也有大小寫不分的版本,名為 istartswith 和 iendswith狭姨。
使用普通查詢宰啦,不同參數(shù)只有“并且”關(guān)系,如果要執(zhí)行更復(fù)雜的查詢饼拍,使用Q表達(dá)式[4]赡模,用&、|惕耕、~代表與或非纺裁,將表達(dá)式作為 filter()
, exclude()
, get()
的參數(shù):
courses = courses.filter(
Q(desc__icontains=k)&Q(content__icontains=k)|
~Q(author__icontains=k)
)
使用Q查詢時先導(dǎo)入from django.db.models import Q
其他高級用法見開發(fā)文檔:其它 QuerySet 方法欺缘。