Django學(xué)習(xí)(4)Model類操作自帶數(shù)據(jù)庫sqlite3

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 方法欺缘。


  1. 數(shù)據(jù)庫配置-Django開發(fā)文檔 ?

  2. 多對多添加的方法 ?

  3. cnblogs-BigJ-雙下劃線查詢總結(jié) ?

  4. 通過 Q 對象完成復(fù)雜查詢 ?

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末栋豫,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子谚殊,更是在濱河造成了極大的恐慌丧鸯,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,454評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件嫩絮,死亡現(xiàn)場離奇詭異丛肢,居然都是意外死亡,警方通過查閱死者的電腦和手機剿干,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,553評論 3 385
  • 文/潘曉璐 我一進(jìn)店門蜂怎,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人置尔,你說我怎么就攤上這事杠步。” “怎么了榜轿?”我有些...
    開封第一講書人閱讀 157,921評論 0 348
  • 文/不壞的土叔 我叫張陵幽歼,是天一觀的道長。 經(jīng)常有香客問我谬盐,道長甸私,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,648評論 1 284
  • 正文 為了忘掉前任飞傀,我火速辦了婚禮皇型,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘助析。我一直安慰自己犀被,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 65,770評論 6 386
  • 文/花漫 我一把揭開白布外冀。 她就那樣靜靜地躺著,像睡著了一般掀泳。 火紅的嫁衣襯著肌膚如雪雪隧。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,950評論 1 291
  • 那天员舵,我揣著相機與錄音脑沿,去河邊找鬼。 笑死马僻,一個胖子當(dāng)著我的面吹牛庄拇,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 39,090評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼措近,長吁一口氣:“原來是場噩夢啊……” “哼溶弟!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起瞭郑,我...
    開封第一講書人閱讀 37,817評論 0 268
  • 序言:老撾萬榮一對情侶失蹤辜御,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后屈张,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體擒权,經(jīng)...
    沈念sama閱讀 44,275評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,592評論 2 327
  • 正文 我和宋清朗相戀三年阁谆,在試婚紗的時候發(fā)現(xiàn)自己被綠了碳抄。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,724評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡场绿,死狀恐怖纳鼎,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情裳凸,我是刑警寧澤贱鄙,帶...
    沈念sama閱讀 34,409評論 4 333
  • 正文 年R本政府宣布,位于F島的核電站姨谷,受9級特大地震影響逗宁,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜梦湘,卻給世界環(huán)境...
    茶點故事閱讀 40,052評論 3 316
  • 文/蒙蒙 一瞎颗、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧捌议,春花似錦哼拔、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,815評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至宫补,卻和暖如春檬姥,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背粉怕。 一陣腳步聲響...
    開封第一講書人閱讀 32,043評論 1 266
  • 我被黑心中介騙來泰國打工健民, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人贫贝。 一個月前我還...
    沈念sama閱讀 46,503評論 2 361
  • 正文 我出身青樓秉犹,卻偏偏與公主長得像蛉谜,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子崇堵,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,627評論 2 350

推薦閱讀更多精彩內(nèi)容