天天看点

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/

此文只是记录,后续还会有其它的文档