十一、【用django2.0來開發】Django的ORM到底如何用——QuerySet
有一周沒寫專欄了, 最近確實有點忙。今天講一下比較中的Django中的ORM吧。本來想融合到項目中的, 但是發現無法全面的講解。 所以單獨拿一章出來講吧
項目demo地址: https://gitee.com/ccnv07/django_example
實例中用到的Model
from django.db import models
class Account(models.Model):
account = models.CharField(max_length=64, blank=True, verbose_name=用戶名)
nickname = models.CharField(max_length=64, blank=True, verbose_name=昵稱)
password = models.CharField(max_length=128, blank=True, verbose_name=密碼)
email = models.EmailField(max_length=32, blank=True, verbose_name=郵箱)
phone = models.CharField(max_length=11, blank=True, verbose_name=手機號)
status = models.IntegerField(
default=1,
blank=True,
verbose_name=狀態,
choices=((1, 啟用), (0, 禁用)))
def __str__(self):
return self.account
class Article(models.Model):
navigation_id = models.IntegerField(default=0, verbose_name=所屬欄目)
thumb = models.CharField(max_length=255, verbose_name=縮略圖, default=)
title = models.CharField(
max_length=64, blank=True, default=, verbose_name=文章標題)
# 如果投稿, 則是會員id, 否則為0(管理員)
author_id = models.IntegerField(default=0, verbose_name=文章作者)
content = models.TextField(blank=True, default=, verbose_name=文章內容)
class Tag(models.Model):
文章標籤類
name = models.CharField(
max_length=32, blank=True, default=, verbose_name=標籤名稱)
class ArticleTagMap(models.Model):
文章和標籤的對應表
article_id = models.IntegerField(default=0)
tag_id = models.IntegerField(default=0)
class Navigation(models.Model):
navigation_name = models.CharField(
max_length=64, blank=True, default=, verbose_name=欄目名稱)
pid = models.IntegerField(default=0, verbose_name=上級欄目)
url = models.CharField(
max_length=32, blank=True, default=, verbose_name=鏈接)
一共有四張表 Account(會員表)、Article(文章表)、Tag(文章標籤表)、ArticleTagMap(文章和標籤對應表)、Navigation(欄目表)
- Account和Article通過Article.author_id建立關聯, 每個會員可以發布多篇文章
- Article和Tag通過ArticleTagMap表關聯, 每個文章可能有多個標籤, 每個標籤下也可能有多個文章
- Article和Navigation通過Article.navigation_id建立關聯, 每個欄目下有多篇文章
新增數據
In [1]: from article.models import Navigation
In [2]: navigation = Navigation(navigation_name=日記, pid=0, url=riji)
In [3]: navigation.save()
In [7]: Navigation.objects.all()
Out[7]: <QuerySet [<Navigation: 日記>, <Navigation: 音樂>, <Navigation: 北京新聞>, <Navigation: 娛樂>, <Navigation: 資訊>, <Navigation: 新聞>]>
只有調用save(), 才會真正執行新增操作
更新數據
通過更新對象來更新數據
In [11]: navigation = Navigation.objects.get(navigation_name=日記)
In [12]: navigation.url = my_note
In [13]: navigation.save()
In [14]: navigation = Navigation.objects.get(navigation_name=日記)
In [15]: navigation.url
Out[15]: my_note
如果對象已經被查詢出來, 然後通過更改模型對象的屬性值, 之後調用save()方法, 則可以更新到數據
使用update方法來更新數據
In [18]: Navigation.objects.filter(navigation_name=日記).update(url=my_note)
Out[18]: 1
In [19]: navigation = Navigation.objects.get(navigation_name=日記)
In [20]: navigation.url
Out[20]: my_note
這句話執行的sql是update navigation set url=my_node where navigation_name=日記
刪除對象
直接通過模型對象的方法刪除
In [21]: navigation.delete()
Out[21]: (1, {article.Navigation: 1})
In [22]: Navigation.objects.all()
Out[22]: <QuerySet [<Navigation: 音樂>, <Navigation: 北京新聞>, <Navigation: 娛樂>, <Navigation: 資訊>, <Navigation: 新聞>]>
如果模型對象已經被查出, 則可以直接指定delete來更新
通過delete方法來刪除
Navigation.objects.filter(navigation_name=日記).delete()
執行的sql就是delete from navigation where navigation_name=日記
查詢數據
all,get,filter和exclude
這四個方法是查詢後最終會返回數據的方法。區別在於
- all() 返回多條數據
- get() 返回一條數據,並且get方法內可以直接指定查詢條件
- filter() 返回指定條件的所有數據
- exclude() 返回除了滿足條件以外的數據
In [23]: Navigation.objects.all()
Out[23]: <QuerySet [<Navigation: 音樂>, <Navigation: 北京新聞>, <Navigation: 娛樂>, <Navigation: 資訊>, <Navigation: 新聞>]>
In [24]: Navigation.objects.get(navigation_name=新聞)
Out[24]: <Navigation: 新聞>
In [25]: Navigation.objects.filter(navigation_name=新聞)
Out[25]: <QuerySet [<Navigation: 新聞>]>
In [26]: Navigation.objects.exclude(navigation_name=新聞)
Out[26]: <QuerySet [<Navigation: 音樂>, <Navigation: 北京新聞>, <Navigation: 娛樂>, <Navigation: 資訊>]>
對比一下區別, 是不是會發現, get()查詢最後返回的是Navigation的模型對象, 而其他三個都返回的是QuerySet對象, QuerySet對象是一個包含了Navigation模型對象的list。
推薦閱讀:
TAG:Django(框架) | DjangoORM | Python |