Django数据模型及操作
转自:http://blog.sina.com.cn/s/blog_a73687bc0101cygy.html
(一) 初始化测试运行环境
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下执行。
(一)创建对象
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)
存在疑问:
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(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/
Django数据模型及操作的更多相关文章
- 【Python】Django数据模型、级联删除、级联更新、ER图导出等
在本文中,我们将向读者详细介绍如何在更新和删除父表数据的同时,触发有关子表数据的级联更新和删除操作.您将看到当使用InnoDB表的时候,借助于外键约束就可以轻松搞定这一过程. 一.利用外键约束更新并删 ...
- Django 2.0 学习(16):Django ORM 数据库操作(下)
Django ORM数据库操作(下) 一.增加表记录 对于表单有两种方式: # 方式一:实例化对象就是一条表记录france_obj = models.Student(name="海地&qu ...
- 从零自学Hadoop(20):HBase数据模型相关操作上
阅读目录 序 介绍 命名空间 表 系列索引 本文版权归mephisto和博客园共有,欢迎转载,但须保留此段声明,并给出原文链接,谢谢合作. 文章是哥(mephisto)写的,SourceLink 序 ...
- 从零自学Hadoop(21):HBase数据模型相关操作下
阅读目录 序 变量 数据模型操作 系列索引 本文版权归mephisto和博客园共有,欢迎转载,但须保留此段声明,并给出原文链接,谢谢合作. 文章是哥(mephisto)写的,SourceLink 序 ...
- Django之Model操作
Django之Model操作 本节内容 字段 字段参数 元信息 多表关系及参数 ORM操作 1. 字段 字段列表 AutoField(Field) - int自增列,必须填入参数 primary_ke ...
- Python之路【第二十二篇】:Django之Model操作
Django之Model操作 一.字段 AutoField(Field) - int自增列,必须填入参数 primary_key=True BigAutoField(AutoField) - bi ...
- Django之ORM操作
Django之ORM操作 前言 Django框架功能齐全自带数据库操作功能,本文主要介绍Django的ORM框架 到目前为止,当我们的程序涉及到数据库相关操作时,我们一般都会这么搞: 创建数据库,设计 ...
- Django之ORM操作(聚合 分组、F Q)
Django之ORM操作(聚合 分组.F Q) 聚合 aggregate()是QuerySet的一个终止子句,也就是说,他返回一个包含一些键值对的字典,在它的后面不可以再进行点(.)操作. 键的名 ...
- Python学习---Django的基础操作180116
Django创建数据库操作 django流程之model实例 settigs.py:更改Django2.0.1的配置,更新为之前的路径配置 'DIRS': [os.path.join(BASE_DIR ...
随机推荐
- 自制一个能显示helloworld的最简单OS
<自己动手写操作系统> org 07c00h mov ax,cs mov ds,ax mov es,ax call DispStr jmp $ DispStr: mov ax,BootMe ...
- iOS JSPatch 热修复使用
概述 一说到热修复,可能很多人会觉得应该很复杂,很难用(我以前是这么觉得的...),实际使用起来蛮简单的,这里以一个小demo演示热修复是如何修复崩溃的,具体更深入的用法,可以看这个https://g ...
- 使用Python的yield实现流计算模式
首先先提一下上一篇<如何猜出Y combinator>中用的方法太复杂了.其实在Lambda演算中实现递归的思想很简单,就是函数把自己作为第一个参数传入函数,然后后面就是简单的Lambda ...
- 菜鸟学习WCF笔记-契约(Contract)
契约,契约确保了服务的正常调用,客户端以契约的方式进行服务端调用,而服务则需要按照契约规定的方式提供服务. 契约是服务提供的一组操作的描述 功能上讲:每个操作对应着某个具体的功能实现,以及调用这个操作 ...
- iOS开发-状态模式
状态模式允许对象内部状态改变时改变它的行为,对象看起来好像修改了它的类.状态模式看起来和策略模式比较相像,策略模式是将可以互换的行为封装起来,然后通过使用委托的方式,决定使用哪一个行为,状态也是封装行 ...
- Bootstrap中水平排列的表单form-inline
<html> <head> <title>初识Bootstrap</title> <meta charset="utf-8"& ...
- javaweb学习总结(二十一)——JavaWeb的两种开发模式
SUN公司推出JSP技术后,同时也推荐了两种web应用程序的开发模式,一种是JSP+JavaBean模式,一种是Servlet+JSP+JavaBean模式. 一.JSP+JavaBean开发模式 1 ...
- Leetcode 125 Valid Palindrome 字符串处理
题意:判断字符串是否是回文字符串 先将所有的字母和数字字符保留,并将大写字母转化成小写字母,然后将字符串倒置,比较前后两个字符串是否相同. 该题最好的解法可以模仿 Leetcode 345 Rever ...
- 利用Mongodb的复制集搭建高可用分片,Replica Sets + Sharding的搭建过程
参考资料 reference: http://mongodb.blog.51cto.com/1071559/740131 http://docs.mongodb.org/manual/tutori ...
- Android Studio使用小技巧:提取方法代码片段
http://www.jb51.net/article/65510.htm 今天来给大家介绍一个非常有用的Studio Tips,有些时候我们在一个方法内部写了过多的代码,然后想要把一些代码提取出来再 ...