天天看點

Django入門:使用技巧【後續會一直添加】【models中的所有field】django注釋django過濾器locals(){{block.super}}擷取父級頁面對應标簽内容{% extends ‘base.html’ %}django modles之objects資料管理器(資料篩選)django完整流程存在疑問:

【models中的所有field】

from django.db import models
class Test(models.Model):
    test = models.ChartField()
#上面的連結就是有關所有models後的所有字段及解釋
           

django注釋

{#。。。。。#}

{% comment %}

Django入門:使用技巧【後續會一直添加】【models中的所有field】django注釋django過濾器locals(){{block.super}}擷取父級頁面對應标簽内容{% extends ‘base.html’ %}django modles之objects資料管理器(資料篩選)django完整流程存在疑問:

django過濾器

{{ name | lower }},将name變量的值轉化成小寫; {{ my_text|escape|linebreaks }} ,轉移文本為html,再轉化每行到

需要參數的過濾器:{{ bio|truncatewords:”30” }} 這個将顯示變量 bio 的前30 個詞。過濾器參數總是使用雙引号辨別。

locals()

def method(request):
    now = datetime.datetime.now()
    return render_to_response('index.html',locals())
    return render_to_response('index.html',{'time':now}) #兩種寫法都可以,locals() 将局部變量都組織成dict 格式,懶人專用
           

{{block.super}}擷取父級頁面對應标簽内容

(1){%block title%}本頁面的title{%endblock%}

(2)一個頁面中不要出現多個同名的block,否則模闆引擎解析将混亂

{% extends ‘base.html’ %}

(1)extends 标記隻能放在最頂部,否則失效

(2)extends 後面跟:一個字元串或者是一個變量

(3)extends 對傳入的模闆名稱,加載方式和get_template(),render_to_response()相同,都是以settings中TEMPLATES_DIRS 為字首

django modles之objects資料管理器(資料篩選)

[轉載位址]

(1)equal

Author.objects.filter(name=’kevin’) 對應的sql語句是:select name,…. where name=’kevin’,為什麼不用select *,而具體指明字段呢,在python界裡有一信條:“ 明确比不明确來的好 ”

filter(name=’kevin’,[key=value])可以傳多個類似的參數,相應會生成多個and 條件後查詢

(2)__like, __in,__iexact, __exact,__contains,__gt,__gte,__lt,__lte,__startswith,__istartswith(sqlite中使用),__endswith,__iendswith(sqlite中使用),__range(start,end)

Author.objects.filter(name__contains=’kevin’) ==>select name,…. where name like ‘%kevin%’

Author.objects.filter(name__in=[‘kevin’,’miao’]) ==>select name,…. where name in(‘kevin’,’miao’)

Author.objects.filter(name__iexact=’kevin’)==>select name,…. where name like ‘kevin’)

Author.objects.filter(name__exact=’kevin’)==>select name,…. where name = ‘kevin’)

Entry.objects.filter(id__gt=4) ==> SELECT … WHERE id > 4;

Entry.objects.filter(id__gte=4) ==> SELECT … WHERE id >= 4;

Entry.objects.filter(id__lt=4) ==> SELECT … WHERE id < 4;

Entry.objects.filter(id__lte=4) ==> SELECT … WHERE id <= 4;

Entry.objects.filter(headline__startswith=’Will’) ==> SELECT … WHERE headline LIKE ‘Will%’;

Entry.objects.filter(headline__endswith=’Will’) ==> SELECT … WHERE headline LIKE ‘%Will’;

start_date=datetime.date(2005,1,1)

end_date=datetime.date(2005,3,31)

Entry.objects.filter(pub_date__range=(start_date,end_date))

SELECT … WHERE pub_date BETWEEN ‘2005-01-01’ and ‘2005-03-31’;

https://docs.djangoproject.com/en/dev/ref/models/querysets/#std:fieldlookup-exact

(5)order_by 排序

Author.objects.all().order_by('name') ,‘ -name ’方序(desc)#即為反序排列

可以在模型中定義内部類Meta,并指明ordering,預設情況下将使用此排序:

def Author(models.Model):
    name = CharField(max_length=)
    #................................................................
    def __str__(self):
        return self.name
    class Meta:
        ordering = ["name"] 
           

(6)限制傳回的資料

Author.objects.all()[0] ===>> select name,…. from Author limit 1

django完整流程

【轉載位址】

(一) 初始化測試運作環境

import os;
import sys;
sys.path.append("G:/pydev/mysite2")    # 需要修改
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "mysite2.settings")    # 需要修改
from qi.models import *
Catalog.objects.all()
Catalog.objects
           

其中Catalog.objects是django.db.models.manager.Manager類型的對對象,Manager是模型(Model)通路資料的操作接口。

擴充

可以為資料模型定義自己的”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下執行。

(二)使用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次資料庫
cl[];  # 在通路1次資料庫

#最好是把所有資料,先周遊一邊,在進行通路:
cl = Catalog.objects.all();
[c.code for c in cl]
cl[];  # 從緩存讀資料
cl[];  # 從緩存讀資料
#  以下四種方法将對象集放進緩存
[c for c in queryset]
bool(queryset)
c in queryset
list(queryset)
           

存在疑問:

1、如何将字元串屬性定義成非空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(,,))
[
           

篩選 : 如果 關系R=A->B 如果重複添加R’=A->B 不知會出現什麼情況?

>>> ringos_membership = Membership.objects.get(group=beatles, person=ringo)
>>> ringos_membership.date_joined
datetime.date(, , )
>>> ringos_membership.invite_reason
           

篩選

>>> ringos_membership = ringo.membership_set.get(group=beatles)
>>> ringos_membership.date_joined
datetime.date(, , )
>>> 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/

此文隻是記錄,後續還會有其它的文檔