Django數據模型及操做

轉自:http://blog.sina.com.cn/s/blog_a73687bc0101cygy.htmlhtml

(一) 初始化測試運行環境python

import os;sql

import sys;數據庫

sys.path.append("G:/pydev/mysite2")   # 須要修改django

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "mysite2.settings")   # 須要修改api

from qi.models import *緩存

Catalog.objects.all()app

Catalog.objectsless

其中Catalog.objects是django.db.models.manager.Manager類型的對對象,Manager是模型(Model)訪問數據的操做接口。eclipse

擴展

能夠爲數據模型定義本身的"manager",具體參考:

https://docs.djangoproject.com/en/1.5/topics/db/managers/#django.db.models.Manager

技巧

import os;

import sys;

sys.path.append("G:/pydev/mysite2")   # 須要修改

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "mysite2.settings")   # 須要修改

能夠放到 Python27\Lib\site-packages\sitecustomize.py 文件中這樣能夠不用每次都輸

因爲目前尚沒法解決命令行的字符集設置問題,全部如下的例子都是在程序文件中編寫並執行。

在mysite2/qi(應用程序目錄)目錄下新建mytest.py,編寫代碼,並在eclipse下執行。

(一)建立對象

Catalog(name="測試",code="test").save();

(二)使用get讀取對象

print(Catalog.objects.get(id=1));

print(Catalog.objects.get(name="根目錄"));

print(Catalog.objects.get(id=1, name="根目錄" , state='A'));

使用get獲取對象的時候如何,若是對象不存在或符合條件的對象超過1個,都將出現異常。

(三)使用filter和exclude

print(Catalog.objects.filter(code__startswith="c", state="A"));

print(Catalog.objects.filter(code__startswith="c", state="A").filter(id = 42));

print(Catalog.objects.filter(code__startswith="c", state="A").exclude(id = 42));

print(Catalog.objects.filter(code__icontains="er"))   # 包含

print(Catalog.objects.filter(code__icontains="i"))   # 包含

其中"__"表示"."的做用,這個由django來轉義。

使用filter能夠容許沒有返回數據,或者多個返回數據。

filter和exclude能夠串聯使用

(四) 簡單日期操做

from datetime import datetime;

from datetime import date;

print(Catalog.objects.filter(create_date__year=2013));   # 時間的年份爲2013年

print(Catalog.objects.filter(create_date__gte=date.today()));   # 時間大於今天

print(Catalog.objects.filter(create_date__gte=datetime(2013, 5, 23))); # 時間大於2013年5月23日

print(Catalog.objects.filter(create_date__lte='2013-05-23'))  # 時間小於2013年5月23日

(五)exists使用

print(Catalog.objects.filter(pk=1).exists())

(六) 用索引器限制記錄的數量

print(Catalog.objects.all())

print(Catalog.objects.all()[:5])

print(Catalog.objects.all()[0:5])

print(Catalog.objects.all()[3:5])

print(Catalog.objects.all()[1:6:2])

print(Catalog.objects.order_by('ord')[0])   # 沒有找到數據會報異常:IndexError: list index out of range

print(Catalog.objects.order_by('ord')[0:1])   # 注意該方法和上1行,同樣是取第1條記錄,可是若是沒有找到數據,這樣寫法不會報異常

print(Catalog.objects.order_by('-ord')[0])   # 倒序排序,取最後一個

(七)exact和iexact使用

print(Catalog.objects.filter(code__exact="public")); 

print(Catalog.objects.filter(code__iexact="PUBLIC"));  # 大小寫不敏感

print(Catalog.objects.filter(code__exact="PUBLIC"));   # 查無數據

默認狀況下執行的是寫code="public"等價於code__exact="public"。

(八)contains和icontains

print(Catalog.objects.filter(code__contains="er"));

print(Catalog.objects.filter(code__icontains="ER")); # 大小寫不敏感

print(Catalog.objects.filter(code__contains="ER")); # 查無數據

code__contains="er"至關於SELECT ... from qi_catalog WHERE code LIKE '%er%';


(九)startswith和endswith

print(Catalog.objects.filter(code__startswith="c"));

print(Catalog.objects.filter(code__endswith="e"));

print(Catalog.objects.filter(code__istartswith="C")); # 大小寫不敏感

print(Catalog.objects.filter(code__iendswith="E"));   # 大小寫不敏感

(十)一對多對象的訪問

print(Catalog.objects.filter(parent__name="根目錄")) # parent = models.ForeignKey('self'); # 訪問根目錄下的全部子目錄

(十一)多對對關係

class Catalog(StateObject)

... ...

papers = models.ManyToManyField(Paper, through='CatalogPaper')

... ...

print(Catalog.objects.filter(papers__name__startswith="公益"))  # 經過papers變量訪問

print(Catalog.objects.filter(catalogpaper__paper__name__startswith="公益"));

# 經過隱含的多對多關係,以上方式特別注意Catalog沒有catalogpaper字段,這是經過隱含多對多關係訪問一樣的方法也能夠用paper對象來訪問catalog,以下:

print(Paper.objects.filter(catalogpaper__catalog__name="公益"))

這種方式訪問關聯對象進行條件組合要注意,串聯filter或exclude是,和直接使用(,..,..)表達是有語義不一樣的,請注意一下兩種寫法,是不一樣的:

print(Catalog.objects.filter(catalogpaper__paper__name="公益問卷1" , catalogpaper__paper__name__startswith='公益問卷2'))  # 不會用數據返回,由於不可能有一個目錄下包含一個問卷名字叫作"公益問卷1"且同時名字又以「公益問卷2」開頭的。

print(Catalog.objects.filter(catalogpaper__paper__name="公益問卷1").filter(catalogpaper__paper__name='公益問卷2')) # 有可能查到數據,此語義爲找一個目錄,其下既有一個名爲「公益問卷1」的問卷,又有一個以「公益問卷2」開頭的問卷(其實是兩個問卷)。

# 經過xxxx_set訪問多對多關係

c = Catalog.objects.get(id=41);

cp = c.catalogpaper_set.all();

for p in cp :

print(p.paper.name)

注意:django中的帶擴展屬性的多對多關係,其實是用一對多的關係實現的,因此咱們實際上也能夠用這種方法訪問多對多關係

(十二)isnull使用

print(Catalog.objects.filter(parent__isnull=True))

未完待續

(十三)使用F()

可使用F()來在等號右邊引用對象查詢中的字段,可是此時彷佛不能用使用startswith,contains等關聯詞,可是能夠用__lt,__lte,__gt,__gte等。

from django.db.models import F;

print(Catalog.objects.filter(name=F('name')))

思考:這裏在等號的右邊不能使用「xx__xxx__xxx」這樣的方式來表示對象的對應屬性,應爲在等號左邊python當成是局部變量的定義,因此怎麼寫都沒有關係。是若是在等號右邊,要嘛是一個已定義變量,要嘛是一個數值或字符串。固然也不能使用字符串來表示對象的屬性,由於會於字符串做爲比較表達式的狀況出現語言混亂,因此django才增長了一個叫作F()的類,解決這樣的問題。

print(Catalog.objects.filter(name__startswith=F('name')))  # 這個會報django.db.utils.DatabaseError: ORA-00909: invalid number of arguments。目前還不知道願緣由。

(十四)in 的使用

print(Catalog.objects.filter(name__in=["商業","社會"]))


參考:https://docs.djangoproject.com/en/1.5/ref/models/querysets/#queryset-api

(十五)字段查詢關鍵字彙總

exact, iexact, contains, icontains, startswith, istartswith, endswith,  iendswith

lt(less than),gt(great than),lte(less than or equal),gte(great than or equal)

in

(十六)緩存機制

# 如下語句要查詢兩次數據庫

print([c.code for c in Catalog.objects.all()])

print([c.name for c in Catalog.objects.all()])

# 如下語句能夠用上django的緩存機制,只用訪問一次數據

cl = Catalog.objects.all();

print([c.code for c in cl])

print([c.name for c in cl])

# 在對象查詢集中使用數據索引要格外當心,由於每次索引都會訪問1次數據庫,即便是訪問同一個元素。注意以下語句:

cl = Catalog.objects.all();

cl[1];  # 訪問1次數據庫

cl[1];  # 在訪問1次數據庫

最好是把全部數據,先遍歷一邊,在進行訪問:

cl = Catalog.objects.all();

[c.code for c in cl]

cl[1];  # 從緩存讀數據

cl[1];  # 從緩存讀數據

#  如下四種方法將對象集放進緩存

[c for c in queryset]

bool(queryset)

c in queryset

list(queryset)

存在疑問:

一、如何將字符串屬性定義成非空null=False 和blank = False彷佛都不生效

https://docs.djangoproject.com/en/1.5/topics/db/queries/

'''   複雜查詢Q()   '''

'''   對象比較   '''

'''   對象刪除   '''

'''   對象拷貝   '''

'''   一次更新多個對象   '''

不帶擴展信息的多對多關係的操做

beatles.members.add(john)

beatles.members.create(name="George Harrison")

beatles.members = [john, paul, ringo, george]

清除關係,是刪除關係仍是刪除數據?

beatles.members.clear()

數據篩選

>>> Group.objects.filter(members__name__startswith='Paul')

[]

篩選

# Find all the members of the Beatles that joined after 1 Jan 1961

>>> Person.objects.filter(

...   group__name='The Beatles',

...   membership__date_joined__gt=date(1961,1,1))

[

篩選 : 若是  關係R=A->B   若是重複添加R'=A->B 不知會出現什麼狀況?

>>> ringos_membership = Membership.objects.get(group=beatles, person=ringo)

>>> ringos_membership.date_joined

datetime.date(1962, 8, 16)

>>> ringos_membership.invite_reason

篩選

>>> ringos_membership = ringo.membership_set.get(group=beatles)

>>> ringos_membership.date_joined

datetime.date(1962, 8, 16)

>>> ringos_membership.invite_reason

u'Needed a new drummer.'

直接執行sql語句

Person.objects.raw('SELECT id, first_name, last_name, birth_date FROM myapp_person')

參考:https://docs.djangoproject.com/en/1.5/topics/db/sql/

相關文章
相關標籤/搜索