Django CRUD操作

Django 中使用ORM模型來定義數(shù)據(jù)庫择克。模型一般是個Python類恬总,類中的屬性對應(yīng)數(shù)據(jù)庫表中的列。 下面是一些增刪改查操作記錄肚邢。

models.py 文件中定義的表結(jié)構(gòu)

# coding=utf-8
from __future__ import unicode_literals

from django.db import models
# django 自帶的認證模塊的表類
from django.contrib.auth.models import User
# Create your models here.


class Host(models.Model):   # 主機表
    # 定義表的字段, 不主動定義主鍵時壹堰,django會自動創(chuàng)建id主鍵,并建立索引骡湖。
    hostname = models.CharField(max_length=64, unique=True)
    ip_addr = models.GenericIPAddressField(unique=True)
    port = models.IntegerField(default=22)
    # 可以選擇機器的系統(tǒng)贱纠,展示給用戶的是數(shù)組中第二個元素,存在數(shù)據(jù)庫中的是第一個元素响蕴。
    system_type_choices = (
        ('linux', "Centos"),
        ('win32', "Windows 7")
    )
    system_type = models.CharField(choices=system_type_choices, max_length=32)
    # 定義主機是否上線并巍,布爾型
    enabled = models.BooleanField(default=True)
    # 創(chuàng)建記錄時間,自動添加
    create_date = models.DateTimeField(auto_now_add=True)
    # 上線時間
    online_date = models.DateTimeField()
    # 主機和組之間是多對多的關(guān)系
    groups = models.ManyToManyField('HostGroup')
    # idc機房换途,外鍵懊渡,并且是一對多的關(guān)系
    idc = models.ForeignKey('IDC')

    def __unicode__(self):
        return self.hostname


class IDC(models.Model):    # IDC機房
    name = models.CharField(max_length=64, unique=True)

    def __unicode__(self):
        return self.name


class HostGroup(models.Model):  # 主機組
    name = models.CharField(max_length=64, unique=True)

    def __unicode__(self):
        return self.name


class UserProfile(models.Model):
    # 使user 一對一的映射 django提供的User
    user = models.OneToOneField(User)
    name = models.CharField(max_length=64, unique=True)
    host_groups = models.ManyToManyField('HostGroup', blank=True, null=True)
    hosts = models.ManyToManyField('Host', blank=True, null=True)

    def __unicode__(self):
        return self.name

使用Djangoshell來操作刽射。

$ python manage.py shell

# 導(dǎo)入
In [1]: from app import models

# 查找
In [2]: models.Host.objects.all()
Out[2]: <QuerySet [<Host: dev-sate>, <Host: pro-sate>, <Host: release-sate>, <Host: sateText2>]>

In [3]: models.IDC.objects.all()
Out[3]: <QuerySet [<IDC: 上海>, <IDC: 北京>]>

# 過濾,filter返回一個列表
In [8]: models.Host.objects.filter(ip_addr='192.168.0.1')
Out[8]: <QuerySet [<Host: dev-sate>]>

# id__lt=1 表示過濾id值小于1的項
In [13]: models.Host.objects.filter(id__lt=1)
Out[13]: <QuerySet []>

# id__gt=1 表示過濾id值大于1的項
In [14]: models.Host.objects.filter(id__gt=1)
Out[14]: <QuerySet [<Host: pro-sate>, <Host: release-sate>, <Host: sateText2>]>

# 多條件過濾剃执,
# hostname__contains(包含誓禁,雙下劃線),包含 sate 的主機名
In [12]: models.Host.objects.filter(system_type='linux', hostname__contains='sate')
Out[12]: <QuerySet [<Host: dev-sate>, <Host: pro-sate>, <Host: sateText2>]>


# 精確查找,get肾档,只能有一個結(jié)果摹恰,如果有多個,則報錯怒见。
In [11]: models.Host.objects.get(system_type='linux', hostname__contains='pro')
Out[11]: <Host: pro-sate>

# 其他的一些查詢用法(未使用上述模型)
# 查看 Django queryset 執(zhí)行的 SQL 
In [1]: print str(Author.objects.all().query)
SELECT "blog_author"."id", "blog_author"."name", "blog_author"."qq", "blog_author"."addr", "blog_author"."email" FROM "blog_author"
### 簡化一下俗慈,就是:SELECT id, name, qq, addr, email FROM blog_author;

# values_list 獲取元組形式結(jié)果
In [6]: authors = Author.objects.values_list('name', 'qq')

In [7]: authors
Out[7]: <QuerySet [(u'WeizhongTu', u'336643078'), (u'twz915', u'915792575'), (u'wangdachui', u'353506297'), (u'xiaoming', u'004466315')]>

# values 獲取字典形式的結(jié)果
In [13]: Author.objects.values('name', 'qq')
Out[13]: <QuerySet [{'qq': u'336643078', 'name': u'WeizhongTu'}, {'qq': u'915792575', 'name': u'twz915'}, {'qq': u'353506297', 'name': u'wangdachui'}, {'qq': u'004466315', 'name': u'xiaoming'}]>

### values_list 和 values 返回的并不是真正的 列表 或 字典,也是 queryset遣耍,他們也是 lazy evaluation 的(惰性評估闺阱,通俗地說,就是用的時候才真正的去數(shù)據(jù)庫查)

多表查詢

首先Djangoadmin控制臺增加一個用戶sate舵变。

# 從 UserProfile 查到用戶名為 sate 的用戶酣溃,并實例化
In [57]: a = models.UserProfile.objects.get(name = 'sate')

# UserProfile表中的hosts字段跟Host表是多對多的關(guān)系,可以根據(jù)該關(guān)系查詢到該用戶所對應(yīng)
#Host表中的各個機器的信息(如 host.hostname, host.ip_addr等)
In [60]: a.hosts.select_related()
Out[60]: <QuerySet [<Host: sateText2>]>

In [20]: h = a.hosts.select_related()[0]

In [22]: h.hostname
Out[22]: u'sateText2'

In [23]: h.ip_addr
Out[23]: u'192.168.0.4'

In [24]: h.create_date
Out[24]: datetime.datetime(2016, 12, 2, 7, 49, 51, 137731, tzinfo=<UTC>)

# 多表查詢 a 中的關(guān)聯(lián)的 host_groups纪隙,同上赊豌。
In [62]: a.host_groups.select_related()
Out[62]: <QuerySet [<HostGroup: dev>, <HostGroup: product>]>
# 可以使用循環(huán)依次讀出處理,但我們這里使用直接賦值绵咱,更清晰碘饼。
In [29]: g = a.host_groups.select_related()[0]  # 選取 dev 組

###  現(xiàn)在我們想獲取dev組中的各個機器的信息,就需要獲取到Host表中的信息悲伶,但和之前有所不
#同艾恼,Host的groups字段對HostGroup表是多對多的,而不是HostGroup的某個字段對Host表是多
#對多拢切,所以如下操作。
In [33]: g.host_set.select_related()
Out[33]: <QuerySet [<Host: dev-sate>, <Host: sateText2>]>

# 同理秆吵,UserProfile 表的host_groups 對HostGroup也是多對多的淮椰。可以進行如下查詢纳寂。
In [34]: g.userprofile_set.select_related()
Out[34]: <QuerySet [<UserProfile: sate>]>

在前端的多表查詢

上邊的查詢主穗,都可以在前端的 html頁面中實現(xiàn)。

{{ request.user.userprofile.hosts.select_related }}
    <ul>
        <!-- 查找登錄用戶所屬的組 -->
        {% for group in request.user.userprofile.host_groups.select_related %}
        <li>{{ group.name }}</li>
            <ul>
            <!-- 通過組查找組內(nèi)機器信息 -->
            {% for host in  group.host_set.select_related  %}
                <li>
                {{ host.hostname }} ===> {{ host.ip_addr }} ===> {{ host.idc.name }}
                </li>
            {% endfor %}
            </ul>
        {% endfor %}
    </ul>

查詢過濾

# 并沒有使用上邊的Model模型毙芜。 只是

#get是用來獲取一個對象的忽媒,如果需要獲取滿足條件的一些人,就要用到filter
Person.objects.filter(name="abc") # 等于Person.objects.filter(name__exact="abc") 名稱嚴格等于 "abc" 的人

Person.objects.filter(name__iexact="abc") # 名稱為 abc 但是不區(qū)分大小寫腋粥,可以找到 ABC, Abc, aBC晦雨,這些都符合條件

Person.objects.filter(name__contains="abc") # 名稱中包含 "abc"的人

Person.objects.filter(name__icontains="abc") #名稱中包含 "abc"架曹,且abc不區(qū)分大小寫

Person.objects.filter(name__regex="^abc") # 正則表達式查詢

Person.objects.filter(name__iregex="^abc")# 正則表達式不區(qū)分大小寫

# filter是找出滿足條件的,當(dāng)然也有排除符合某條件的
Person.objects.exclude(name__contains="WZ") # 排除包含 WZ 的Person對象

Person.objects.filter(name__contains="abc").exclude(age=23) # 找出名稱含有abc, 但是排除年齡是23歲的

# 增加一條Host的新紀錄闹瞧。online_date 是時間類型绑雄,所以要導(dǎo)入datetime模塊,生成時間奥邮。
In [15]: import datetime
# 添加一條記錄万牺,需要注意的是 idc 是個外鍵,如果直接知道所屬idc的id洽腺,可以使用 'idc_id = 1'的方式來添加記錄脚粟。
In [18]: models.Host.objects.create(
    ...: hostname = 'NewHost',
    ...: ip_addr = '192.168.0.6',
    ...: port = 22,
    ...: system_type = 'linux',
    ...: idc = models.IDC.objects.get(name='北京'),   # 或使用 idc_id = 1 的方式來設(shè)定
    ...: online_date = datetime.datetime.now())
/Users/zheng/VirtualEnv/just_python2/lib/python2.7/site-packages/django/db/models/fields/__init__.py:1430: RuntimeWarning: DateTimeField Host.online_date received a naive datetime (2016-12-05 09:21:41.926206) while time zone support is active.
  RuntimeWarning)
Out[18]: <Host: NewHost>
# 上邊有warning信息,是因為時區(qū)的原因蘸朋。此時生成的日期核无,并不是當(dāng)前時區(qū)的時間。
# 現(xiàn)在還有問題是 有個多對多的 groups 字段不能用上邊方式定義度液,使用如下方法定義
In [19]: new = models.Host.objects.get(hostname='newhost')
# 現(xiàn)在為他添加所有的組厕宗,先查出所有組
In [25]: all_groups = models.HostGroup.objects.all()
In [26]: all_groups
Out[26]: <QuerySet [<HostGroup: dev>, <HostGroup: product>]>
# 為 new 添加查出來的組,方式為 new.groups.add(1,2)
In [30]: new.groups.add(*[i.id for i in all_groups])
# 然后再Django的admin后臺頁面查看堕担,會發(fā)現(xiàn)改機器已經(jīng)屬于所有組已慢。

# 如果要刪除該機器的所屬組,可以使用remove 替換 add
In [31]: new.groups.remove(*[i.id for i in all_groups])


### 上邊方法比較麻煩霹购,可以使用如下方法
# 先實例化
In [33]: h = models.Host(
    ...: hostname = 'NewHost2',
    ...: ip_addr = '192.168.0.7',
    ...: port = 33,
    ...: system_type='linux',
    ...: idc_id=1,
    ...: online_date=datetime.datetime.now())
# 寫入數(shù)據(jù)庫
In [35]: h.save()
# 添加 groups 的多對多的關(guān)系
In [36]: all_groups = models.HostGroup.objects.all()
In [37]: h.groups.add(*[i.id for i in all_groups])

### 指定修改
In [39]: gai = models.Host.objects.get(hostname='Newhost')
In [41]: gai.hostname = 'NewHost1'
In [43]: gai.save()

### 批量修改
# 全部修改
In [45]: models.Host.objects.all().update(port=2000)
Out[45]: 6L
# 過濾修改
In [47]: models.Host.objects.filter(system_type='linux').update(port=22, system_type='win32')
Out[47]: 5L

### 指定刪除
In [50]: gai = models.Host.objects.get(hostname='Newhost1')

In [51]: gai.delete()
Out[51]:
(3L,{u'app01.Host': 1L, u'app01.Host_groups': 2L, u'app01.UserProfile_hosts': 0L})

### 批量刪除
In [53]: models.Host.objects.filter(port=2000).delete()
Out[53]:
(3L,
 {u'app01.Host': 1L, u'app01.Host_groups': 1L, u'app01.UserProfile_hosts': 1L})
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末佑惠,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子齐疙,更是在濱河造成了極大的恐慌膜楷,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,657評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件贞奋,死亡現(xiàn)場離奇詭異赌厅,居然都是意外死亡,警方通過查閱死者的電腦和手機轿塔,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,889評論 3 394
  • 文/潘曉璐 我一進店門特愿,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人勾缭,你說我怎么就攤上這事揍障。” “怎么了俩由?”我有些...
    開封第一講書人閱讀 164,057評論 0 354
  • 文/不壞的土叔 我叫張陵毒嫡,是天一觀的道長。 經(jīng)常有香客問我幻梯,道長兜畸,這世上最難降的妖魔是什么努释? 我笑而不...
    開封第一講書人閱讀 58,509評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮膳叨,結(jié)果婚禮上洽洁,老公的妹妹穿的比我還像新娘。我一直安慰自己菲嘴,他們只是感情好饿自,可當(dāng)我...
    茶點故事閱讀 67,562評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著龄坪,像睡著了一般昭雌。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上健田,一...
    開封第一講書人閱讀 51,443評論 1 302
  • 那天烛卧,我揣著相機與錄音,去河邊找鬼妓局。 笑死总放,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的好爬。 我是一名探鬼主播局雄,決...
    沈念sama閱讀 40,251評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼存炮!你這毒婦竟也來了炬搭?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,129評論 0 276
  • 序言:老撾萬榮一對情侶失蹤穆桂,失蹤者是張志新(化名)和其女友劉穎宫盔,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體享完,經(jīng)...
    沈念sama閱讀 45,561評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡灼芭,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,779評論 3 335
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了般又。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片彼绷。...
    茶點故事閱讀 39,902評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖倒源,靈堂內(nèi)的尸體忽然破棺而出苛预,到底是詐尸還是另有隱情句狼,我是刑警寧澤笋熬,帶...
    沈念sama閱讀 35,621評論 5 345
  • 正文 年R本政府宣布,位于F島的核電站腻菇,受9級特大地震影響胳螟,放射性物質(zhì)發(fā)生泄漏昔馋。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,220評論 3 328
  • 文/蒙蒙 一糖耸、第九天 我趴在偏房一處隱蔽的房頂上張望秘遏。 院中可真熱鬧,春花似錦嘉竟、人聲如沸邦危。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,838評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽倦蚪。三九已至,卻和暖如春边苹,著一層夾襖步出監(jiān)牢的瞬間陵且,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,971評論 1 269
  • 我被黑心中介騙來泰國打工个束, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留慕购,地道東北人。 一個月前我還...
    沈念sama閱讀 48,025評論 2 370
  • 正文 我出身青樓茬底,卻偏偏與公主長得像沪悲,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子桩警,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,843評論 2 354

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