Chinaunix首页 | 论坛 | 博客
  • 博客访问: 29990673
  • 博文数量: 2065
  • 博客积分: 10377
  • 博客等级: 上将
  • 技术积分: 21525
  • 用 户 组: 普通用户
  • 注册时间: 2008-11-04 17:50
文章分类

全部博文(2065)

文章存档

2012年(2)

2011年(19)

2010年(1160)

2009年(969)

2008年(153)

分类: Python/Ruby

2009-08-04 10:05:30

1.基本数据访问
publisher_list = Publisher.objects.all()
后台相当于执行了一条SQL语句SELECT语句
2.插入和更新数据
p = Publisher(name='Apress', ... address='2855 Telegraph Ave.', ... city='Berkeley', ... state_province='CA', ... country='U.S.A.', ... website='')
利用构造函数得到一个对象。相当于传统MVC中给SET方法了!
p.save() 后台相当于执行了一个INSERT语句的!
p.id     插入之后会返回其自增长的ID值。即类似于PHP中的一个函数的!
接着:
p.name = 'Apress Publishing'
p.save() 后台相当于执行了一个UPDATE语句的!
3.选择对象
Publisher.objects.all()
相当于SQL语句:
SELECT id, name, address, city, state_province, country, website FROM book_publisher;
4.数据过滤
Publisher.objects.filter(name="Apress Publishing")
相当于SQL语句:
SELECT id, name, address, city, state_province, country, website FROM book_publisher WHERE name = 'Apress Publishing'; 条件性过滤处理
Publisher.objects.filter(country="U.S.A.", state_province="CA")
相当于:
SELECT id, name, address, city, state_province, country, website FROM book_publisher WHERE country = 'U.S.A.' AND state_province = 'CA';
两个条件查询的!
实现SQL中的模糊查询的方法
Publisher.objects.filter(name__contains="press")
相当于的SQL语句如下:
SELECT id, name, address, city, state_province, country, website FROM book_publisher WHERE name LIKE '%press%';
这些都是放到视图层处理。得到数据集或更新表。如果有涉及到多表联合查询的话就要考虑使用原生CURSOR

5。获取单个对象
Publisher.objects.get(name="Apress Publishing")
这样,就返回了单个对象,而不是列表(更准确的说,QuerySet)。所以,如果结果是多个对象,会导致抛出异常:
相当于用户登录系统这种唯一性的时候就可以考虑使用这种方法的!只有唯一的一个值了!

6.数据排序
Publisher.objects.order_by("name")
等价的SQL语句:
SELECT id, name, address, city, state_province, country, website FROM book_publisher ORDER BY name;
对于排序也可以放到模型层去处理。指定默认的排序方式即可!
在这种情况下,Django让你可以指定模型的缺省排序方式
**class Meta:** **ordering = ["name"]**
这样的话就会默认会有排序操作的!

同时做排序与过滤
Publisher.objects.filter(country="U.S.A.").order_by("-name")
慢慢来构造出来比较复杂的SQL查询语句了!
其:
SELECT id, name, address, city, state_province, country, website FROM book_publisher WHERE country = 'U.S.A' ORDER BY name DESC;

7.限制返回的数据(返回limit)
Publisher.objects.all()[0]
相当的SQL语句:
SELECT id, name, address, city, state_province, country, website FROM book_publisher ORDER BY name LIMIT 1; 限制返回的记录个数

8.要删除对象,只需简单的调用对象的 delete() 方法
p = Publisher.objects.get(name="Addison-Wesley") 得到单独的一条记录
p.delete()

通常更好的方法是给你的数据模型添加激活标志。你可以只在激活的对象中查找,对于不需要的对象,将激活字段值设为 False , 而不是删除对象。这样,如果一旦你认为做错了的话,只需把标志重设回来就可以了。
为了确保数据的完整性!不能进行物理性删除的!


9.修改数据库表结构

修改表结构也就是按照正确的顺序修改各种Python代码和数据库本身(如果你需要修改表结构的话就要这样处理了。手工修改PYTHON代码与数据库本身)

9.1添加字段

   先在数据库中添加列,然后再改变模型中对应的字段。
就是修改数据库结构与模型中的内容的!

首先,在开发环境中执行下面的步骤(也就是说,不是在发布服务器上):

  1. 把这个字段添加到你的模型中.(第一步:定义到模型层中去新增一个字段出来)

  1. 运行 manage.py sqlall [yourapp] 会看到模型的新的 CREATE TABLE 语句。注意新的字段的列定义。(查看到具体的SQL语句)

  1. 启动您的数据库交互shell(也就是 psqlmysql , 或者您也可以使用 manage.py dbshell )。 执行一个 ALTER TABLE 语句,添加您的新列。

4. (可选)用 manage.py shell 启动Python交互式shell,并通过引入模型并选择表验证新的字段已被正确添加(比如, MyModel.objects.all()[:5] )。

删除、修改字段都是一样的操作。先修改模型层的代码然后再

(目前系统中不考虑使用多对多或一对多的情况的)

10.删除模型
将此模型从你的 models.py 文件里删除,并且重启Web服务器。
然后数据库那边直接不要


数据库API实现ORM必备!

1.自增主键
b2 = Blog(name='Cheddar Talk', tagline='Thoughts on cheese.')
b2.save()
b2.id           #php有类似的功能

2.获取对象
blogs = Blog.objects.filter(author__name__contains="Joe")
QuerySet 代表了你的数据库中的对象的一个集合。它根据所给参数可以构造若干个 过滤器 来缩小这个集合的规模。用SQL术语来讲,一个 QuerySet 就相当于一个 SELECT 语句,过滤器相当于诸如 WHERE 或者 LIMIT 的限定语

3.缓存与查询集

为了减少数据库访问次数,每个 QuerySet 包含一个缓存,要写出高效的代码,理解这一点很重要。

在刚被创建的 QuerySet 中,缓存是空的。当 QuerySet 第一次被赋值,就是执行数据库查询的时候,Django会把查询结果保存到这个 QuerySet 的缓存中,并返回请求结果(例如, QuerySet 迭代结束的时候,就会返回下一条记录)。再次使用 QuerySet 的值的话会重复使用缓存中的内容。

非常地跟memecherad相似哦!

实现的方法如下:

queryset = Poll.objects.all() #得到一个queryset数据集能够存在缓存

print [p.headline for p in queryset] # Evaluate the query set.

4.过滤器

加一些过滤条件。用 filter()exclude() 方法可以实现这样的功能

5.级联过滤器

对我们的结果集进一步过滤处理!

细化过的 QuerySet 本身就是一个 QuerySet ,所以可以进一步细化。

>>> qs = Entry.objects.filter(headline__startswith='What') 

会得到一个结果集出来!

>>> qs = qs..exclude(pub_date__gte=datetime.datetime.now()) 

在此基础上进一步过滤处理!

6.限量查询集

可以用Python的数据切片的语法来限定 QuerySet 的结果数量,这和SQL中的 LIMITOFFSET 语句是一样的。

比如,这句返回前五个条目( LIMIT 5 ):

>>> Entry.objects.all()[:5]

filter(**lookup)

返回一个新的 QuerySet ,包含匹配参数lookup的对象。

exclude(**kwargs)

返回一个新的 QuerySet ,包含不匹配参数kwargs的对象。

order_by(*fields)

默认情况下,会返回一个按照models的metadata中的``ordering``选项排序的``QuerySet``(请查看附录B)。你可以调用``order_by()``方法按照一个特定的规则进行排序以覆盖默认的行为:


要使用随机的顺序,使用 "?" ,比如:

>>> Entry.objects.order_by('?')  随机排序处理操作!

7.select_related()
e = Entry.objects.get(id=5)
b = e.blog 这样的话还会再去请求一次数据库服务器的!
如果这样写的:e = Entry.objects.select_related().get(id=5)
然后:
b = e.blog 就不会再去请求服务器了!


1.

get(**lookup)

get() raises a DoesNotExist exception if an object wasnt found for the given parameters (如果没有记录存在就会有异常出现)
from django.core.exceptions import ObjectDoesNotExist
>>> try: ... e = Entry.objects.get(id=3) ... b = Blog.objects.get(id=1) ... except ObjectDoesNotExist: ... print "Either the entry or blog doesn't exist."

create(**kwargs)

这个快捷的方法可以一次性完成创建并保证对象。它让你完成了下面两个步骤:

>>> p = Person(first_name="Bruce", last_name="Springsteen")
>>> p.save()

into a single line:

>>> p = Person.objects.create(first_name="Bruce", last_name="Springsteen")
传统的方法是通过
1.构造出来对象
2.调用save方法处理。现在不用直接使用create即可!

try:
obj = Person.objects.get(first_name='John', last_name='Lennon')
except Person.DoesNotExist:
obj = Person(first_name='John', last_name='Lennon', birthday=date(1940, 10, 9))
obj.save()
为了不保存重复的记录可以这样处理哦!
这种方法如可以使用如下的方法代替出来!
obj, created = Person.objects.get_or_create(
first_name = 'John',
last_name = 'Lennon',
defaults = {'birthday': date(1940, 10, 9)}
)

2.count()
返回记录集的个数。即QuerySet的个数!
Entry.objects.count()
Entry.objects.filter(headline__contains='Lennon').count()
可以返回当前数据集的记录条数!

相当于: SELECT COUNT(*)


3.latest(field_name=None)
Entry.objects.latest('pub_date')
能够查询出来最新的记录!

4.exact
>>> Blog.objects.get(id__exact=14) # Explicit form
>>> Blog.objects.get(id=14) # __exact is implied
这两个语句实现的功能是一样的!

contains (区分大小写关系)

执行严格区分大小写的内容包含检测:

Entry.objects.get(headline__contains='Lennon')

这将会匹配标题为``’Today Lennon honored’`` 的,而不匹配 ‘today lennon honored’。

icontains (不区分大小写)

执行一个忽略大小写的内容包含检测:

>>> Entry.objects.get(headline__icontains='Lennon')

与``contains``不同, icontains 匹配 'today lennon honored'


gt, gte, lt, and lte

这些即大于,大于或等于,小于,小于或等于:

>>> Entry.objects.filter(id__gt=4)
>>> Entry.objects.filter(id__lt=15)
>>> Entry.objects.filter(id__gte=0)

过滤的时候使用的逻辑连接词

in

筛选出包含在给定列表中的数据:

Entry.objects.filter(id__in=[1, 3, 4])

这会返回所有ID为1,3,或4的条目。


startswith

区分大小写的开头匹配:

>>> Entry.objects.filter(headline__startswith='Will')

这将返回标题Will he run?和Willbur named judge,但是不会返回Who is Will? 和will found in crypt.

istartswith

Performs a case-insensitive starts-with:

>>> Entry.objects.filter(headline__istartswith='will')


range

Performs an inclusive range check:

>>> start_date = datetime.date(2005, 1, 1) >>> end_date = datetime.date(2005, 3, 31) >>> Entry.objects.filter(pub_date__range=(start_date, end_date))

查询日期的时候能够介于两个时间值之间处理的!

isnull

使用``True``或``False``,则分别相当于SQL语句中的``IS NULL``和``IS NOT NULL``:

>>> Entry.objects.filter(pub_date__isnull=True)

回归原始的SQL操作

如果你需要写一个SQL查询,但是用Django的数据库映射来实现的话太复杂了,那么你可以考虑使用原始的SQL语句。

解决这个问题的比较好的方法是,给模块写一个自定义的方法或者管理器方法来执行查询。尽管在Django中,数据库查询在模块中没有任何存在的 必要性 ,但是这种解决方案使你的数据访问在逻辑上保持一致,而且从组织代码的角度讲也更灵活。操作指南见附录B。

最后,请记住Django的数据库层仅仅是访问数据库的一个接口,你可以通过其他的工具、编程语言或者数据库框架来访问数据库,它并不是特定于Django使用的。


可以考虑使用ORM也可以使用原生SQL语句!









 








阅读(602) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~