前述內容設置了一個全功能管理站點,並可對博客內容進行處理.本節將討論如何從數據庫中獲取信息並與其進行交互.Django設置了強大的數據庫抽象API,並以此方便地建立、獲取、更新以及刪除對象.同時,Django中的對象關係映射器兼容於MySQL、PostgreSQL、SQLite、Oracle.須要注意的是,咱們可在項目的settings.py文件中的DATABASES設置項中定義當前項目的數據庫.Django可一次與多個數據庫協同工做,用戶能夠對數據庫路由器進行編程,以建立自定義路由方案.python
在數據庫模型建立完畢後,Django提供了相應的API可與其進行交互.shell
1.5.1 建立對象數據庫
打開終端並運行如下命令啓動Python shell:django
python manage.py shell
隨後輸入下列代碼行編程
from django.contrib.auth.models import User from blog.models import Post user = User.objects.get(username='admin') post = Post(title='Another post',slug='another-post',body='Post body',author=user) post.save()
下面對上述代碼的執行內容進行簡要分析.首先,咱們經過用戶名admin獲取user對象,以下所示:緩存
user = User.objects.get(username='admin')
這裏,get()方法可從數據庫中獲取單一對象.注意,該方法指望獲得與查詢匹配的結果.若是數據庫未返回任何結果,該方法將會拋出DoesNotExist異常:若是數據庫返回多條結果,則會拋出MultipleObjectsReturned異常.這兩個異常均爲與執行查詢對應的、模型類的屬性.服務器
隨後利用定製title、slug以及body建立Post實例,並將以前檢索到的用戶設置爲帖子的做者,以下所示:post
post = Post(title='Another post',slug='another-post',body='Post body',author=user)
!!!注意:測試
此類對象位於內存中,且未實現數據庫的持久化操做.spa
最後,利用save()方法將Post對象保存至數據庫,以下所示:
post.save()
上述操做在後臺執行了INSERT SQL語句.前述內容討論了在內存中建立對象,並於隨後將其持久化至數據庫中.除此以外,還可經過create()這一單一操做方式建立對象,並將其持久化至數據庫中,以下所示:
Post.objects.create(title='One more post',slug='one-more-post',body='Post body.',author=user)
1.5.2 更新對象
下面修改帖子的標題,並再次保存對象,對應代碼以下所示:
post.title = 'New title' post.save()
此處,save()方法執行UPDATE SQL語句.
!!!注意:
當調用了save()方法後,對象的變化內容方能持久化至數據庫中.
1.5.3 獲取對象
Django對象關係映射機制(ORM)基於Queryset.Queryset表示爲一個源自數據庫的對象集合,其中包含了多個過濾器以對結果進行限制.咱們瞭解到經過get()方法獲取數據庫中的單一對象,並利用Post.objects.get()訪問該方法.相應的,每一個Django模型至少包含一個管理器,且默認管理器稱做objects.經過模型管理器,用戶可獲得一個Queryset對象.當從某個表中獲取全部的對象時,僅需使用默認對象管理器上的all()方法便可,以下:
all_posts = Post.objects.all()
上述代碼顯示了Queryset的建立方式,並返回數據庫中的所有對象.注意,該Queryset還沒有被執行.Django中的Queryset具備延遲性,僅在強制操做下方得以被執行,這種行爲使得Queryset更加高效.若是未將Queryset設置爲某個變量,而是直接將其寫入python shell中,Queryset的SQL語句將被執行--此處將其強制至輸出結果中,以下:
Post.objects.all()
1.使用filter()方法
當過濾Queryset時,可食用管理器的filter()方法.例如,可利用下列Queryset得到2019年中發佈的所有帖子:
Post.objects.filter(publisher__year=2019)
除此以外,還可經過多個字段進行過濾.例如,可經過包含用戶名admin的做者獲取發佈於2019年的全部帖子,以下:
Post.objects.filter(publisher__year=2019,author__username='admin')
這至關於構建連接多個過濾器的同一Queryset,以下:
Post.objects.filter(publish__year=2017).filter(author__username='admin')
!!!注意:
包含字段查找方法的查詢操做可採用兩個下劃線予以構建,如publish__year;但同一標記也可用於相關模型的訪問字段,如author__username.
2.使用exclude()方法
利用過濾器的exclude()方法,可從Queryset中排除特定的結果.例如,可獲取標題不包含test的、發佈於2019年的所有帖子,以下:
Post.objects.filter(publish__year=2019).exclude(title__startswith='test')
3.使用order_by()方法
利用管理器的order_by()方法,可經過不一樣的字段對結果進行排序.例如,可獲取以標題排序的所有對象,以下:
Post.objects.order_by('title')
這裏,默認爲升序操做.固然還可經過負號前綴進行降序排序,以下:
Post.objects.order_by('-title')
1.5.4 刪除對象
若是但願刪除某個對象,可經過delete()方法在對象實例中執行這一操做,以下:
post = Post.objects.get(id=1)
post.delete()
!!!注意:
刪除對象也會刪除ForeignKey對象(on_delete設置爲CASCADE)的依賴關係.
1.5.5 評估Queryset
咱們能夠鏈接多個過濾器到一個Queryset上,在Queryset計算以前並不會訪問數據庫.Queryset僅在如下場合被計算.
1.5.6 建立模型管理器
如前所述,對象表示爲每一個模型的默認管理器(可檢索數據庫中的所有對象).然而,咱們還可針對模型定義定製管理器.下面將建立定製管理器並檢索包含published狀態的所有帖子.
對此,存在兩種方式可向模型中添加管理器,即添加額外的管理器方法,或者修改初始管理器Queryset.其中,第一個方法提供了相應的Queryset API,如Post.objects.my_manager();而第二個方法則提供了Post.my_manager.all().該管理器可經過Post.published.all()檢索帖子.
下面編輯models.py文件並添加定製管理器,以下:
class PublishedManager(models.Manager): def get_queryset(self): return super(PublishedManager,self).get_queryset().filer(status='published') class Post(models.Model): # ... objects = models.Manager() # 默認manager published = PublishedManager() # 定製的manager
管理器的get_queryset()方法返回將被執行的Queryset.咱們將覆寫該方法,以在最終的Queryset中包含自定義過濾器.以前曾定義了定製管理器,並將其添加值Post模型中,此處可對其加以使用並執行查詢.
經過如下命令再次啓用開發服務器:
python manage.py shell
此處可利用下列命令檢索全部發布的帖子,其對應的標題以test開始
Post.published.filter(title__startswith='test')