您的位置:首页 > 数据库

django 数据库API参考(下)

2012-12-11 16:35 281 查看

django 数据库API参考(下)

dates(field, kind, order='ASC')

每个管理器拥有一个 dates() 方法, 它返回一个datetime.datetime 对象的列表, 表示经过给定的过滤器(由kind
参数定义)过滤后的所有可用的 dates .

field 是 model 模块中的一个DateField 或DateTimeField 属性名.

kind 是"year","month" 或"day"
中的一个. 结果列表中的每个datetime.datetime 对象被截短为给定的type 形式.

"year" 返回一个该字段的不重复的年的列表.
"month" 返回一个该字段的不重复的年/月的列表.
"day" 返回一个该字段的不重复的年/月/日的列表.

order 只能是"ASC" 或"DESC", 默认值是'ASC'.
它指定如何排序结果.

这里有一个例子, 使用上面定义的 Poll model

>>> from datetime import datetime
>>> p1 = Poll(slug='whatsup', question="What's up?",
...      pub_date=datetime(2005, 2, 20), expire_date=datetime(2005, 3, 20))
>>> p1.save()
>>> p2 = Poll(slug='name', question="What's your name?",
...      pub_date=datetime(2005, 3, 20), expire_date=datetime(2005, 4, 20))
>>> p2.save()
>>> Poll.objects.dates('pub_date', 'year')
[datetime.datetime(2005, 1, 1)]
>>> Poll.objects.dates('pub_date', 'month')
[datetime.datetime(2005, 2, 1), datetime.datetime(2005, 3, 1)]
>>> Poll.objects.dates('pub_date', 'day')
[datetime.datetime(2005, 2, 20), datetime.datetime(2005, 3, 20)]
>>> Poll.objects.dates('pub_date', 'day', order='DESC')
[datetime.datetime(2005, 3, 20), datetime.datetime(2005, 2, 20)]
>>> Poll.objects.filter(question__contains='name').dates('pub_date', 'day')
[datetime.datetime(2005, 3, 20)]


select_related()

关系是数据库的根本, select_related() 方法"追踪" 所有的关系对象, 并将它们预先存放到一个简单的缓存中.这样当需要调用一个具有一对多关系的对象时就不必再次访问数据库.要做到这一点, 只需对一个结果集使用select_related()
方法.这可能导致(某些时候相当)大的(有可能是不必要的)查询, 但这却意味着后续的关系使用会快很多.(俺的建议:对一个频繁变化的多用户数据库,不要使用该参数)

举例来说, 上面的 Poll 和 Choice models 中, 如果你这样做:

c = Choice.objects.select_related().get(id=5)

那么后面的 c.poll() 将不用访问数据库.

注意这个 select_related 方法会尽可能远的追踪外键. 如果你有下面的 models:

class Poll(models.Model):
# ...

class Choice(models.Model):
# ...
poll = models.ForeignKey(Poll)

class SingleVote(meta.Model):
# ...
choice = models.ForeignKey(Choice)

那么调用 SingleVotes.objects.select_related().get(id=4) 会缓存相关的 choice和 相关的 poll:

>>> sv = SingleVotes.objects.select_related().get(id=4)
>>> c = sv.choice         # Doesn't hit the database.
>>> p = c.poll            # Doesn't hit the database.

>>> sv = SingleVotes.objects.get(id=4)
>>> c = sv.choice         # Hits the database.
>>> p = c.poll            # Hits the database.


extra(params, select, where, tables)

有时候, Django 提供的查询语法不太够用. 为了满足这些边缘需求, Django 提供了
extra() 结果集修改器 - 一种提供额外查询参数的机制.

要注意这些额外的方式对不同的数据库引擎可能存在移植性问题.(因为你在显式的书写SQL语句),除非万不得已,尽量避免这样做:

params

下面描述的所有 额外-SQL 参数都必须是标准 Python 字符串格式(数据库引擎会自动用引号将它引起).``params`` 参数可以包含任意多个的SQL参数.

select

select 关键字参数允许你选择特定的字段. 它是一个字典(属性名与 SQL 语句的映射). 举例来说:

Poll.objects.extra(
select={
'choice_count': 'SELECT COUNT(*) FROM choices WHERE poll_id = polls.id'
}
)

每个返回的 ``Poll`` 对象会有一个额外的属性: ``choice_count``, 一个关联`` Choice`` 对象的整数. 注意大多数数据库引擎需要用括号将子查询括起来. Django 的 ``select`` 子句则不需要这个括号.

where /tables如果你需要传递一个额外的 WHERE 子句 -- 比方进行一个非显式的连接--你可以使用where 关键字参数. 如果你需要在查询中连接其它的表,你可以传递它们的名字给tables
参数.
where 和tables 都接受一个字符串列表作为它们的值.所有的where 参数都被 "AND"
到其它的查询条件中.

举例来说:

Poll.objects.filter(
question__startswith='Who').extra(where=['id IN (3, 4, 5, 20)'])

...翻译成 SQL 语句就是::

SELECT * FROM polls_polls WHERE question LIKE 'Who%' AND id IN (3, 4, 5, 20);


改变对象

一旦你使用任何上面介绍的方法从数据库中得到一个对象, 改变这个对象就是相当容易的一件事情了.直接操作这些对象的字段,然后调用save() 方法保存它们:

>>> p = Poll.objects.get(id__exact=15)
>>> p.slug = "new_slug"
>>> p.pub_date = datetime.datetime.now()
>>> p.save()


创建对象

通过创建一个新的实例并调用 save() 保存之,就可以创建一个新的数据记录(也就是 INSERT):

>>> p = Poll(slug="eggs",
...                 question="How do you like your eggs?",
...                 pub_date=datetime.datetime.now(),
...                 expire_date=some_future_date)
>>> p.save()

一个主键值为 None 的对象调用save() 方法表示这是一个新记录,应该被插入到数据表中.

通过便利方法(convenience function)可以很容易的创建关联对象 (比如
Choices):

>>> p.choice_set.create(choice="Over easy", votes=0)
>>> p.choice_set.create(choice="Scrambled", votes=0)
>>> p.choice_set.create(choice="Fertilized", votes=0)
>>> p.choice_set.create(choice="Poached", votes=0)
>>> p.choice_set.count()
4

这些 add_choice 方法于下面的函数等价(却更简单):

>>> c = Choice(poll_id=p.id, choice="Over easy", votes=0)
>>> c.save()

注意当使用这种 add_foo()` 方法时, 你不要给 id 字段提供任何值, 也不要给保存关系的字段提供任何值.(此处是poll_id ).

这类 add_FOO() 方法总是返回刚刚创建的对象.

删除对象

如同你想象的一样,删除对象的方法是 delete(). 该方法立即删除该对象并返回 None.比如:

>>> c.delete()

通过使用同样的查询条件(参数), get_object 和其它查询方法也可以用来批量删除对象. 比如:

>>> Polls.objects.filter(pub_date__year=2005).delete()

此举将删除2005年的所有民意测验数据. 注意 delete() 是唯一一个管理器对象不能直接访问的结果集方法. 这提供了一种安全机制,可以避免发生意外事故: 否则Poll.objects.delete(), 将删除所有的
投票.

如果你 真的 想删除表中的所有数据,你只能这么做:

Polls.objects.all().delete()

此举将从数据库中删除所有的 Poll 实例.

比较对象

要比较两个 model 对象, 使用标准的 Python 比较运算符,即双等号: ==. (在幕后进行比较的是两个对象的 主键 的值).

仍然是上面的 Poll 例子, 下面两个语句是等价的:

some_poll == other_poll
some_poll.id == other_poll.id

如果一个 model 的主键名字不是 ID, 没问题, 比较总是发生在主键之间,不管它叫什么名字. 举例来说, 如果一个 model 的主键字段叫name, 则下面这两个语句是等价的:

some_obj == other_obj
some_obj.name == other_obj.name


其它实例方法

除了 save(),delete() 和所有的add_* 及get_*
关联对象方法之外,一个 model 对象可能还拥有下面的部分或全部方法:

get_FOO_display()

如果一个字段有 choices 选项集事, 这个对象将有一个get_FOO_display() 方法.这里FOO
是该字段的名字. 这个方法返回一个 "human-readable" 的字段值. 举例来说, 下面的model中:

GENDER_CHOICES = (
('M', 'Male'),
('F', 'Female'),
)
class Person:
name = models.CharField(maxlength=20)
gender = models.CharField(maxlength=1, choices=GENDER_CHOICES)

...每个 Person 实例会拥有一个get_gender_display() 的方法. 示例:

>>> p = Person(name='John', gender='M')
>>> p.save()
>>> p.gender
'M'
>>> p.get_gender_display()
'Male'


get_next_by_FOO(**kwargs) 和 get_previous_by_FOO(**kwargs)

不存在 null=True 的每个DateField 和DateTimeField 自动拥有get_next_by_FOO()
和get_previous_by_FOO() 方法, 此处的FOO 是字段的名字. 它们分别返回该字段的上一个对象和下一个对象. 如果上一对象或下一对象不存在,则抛出*DoesNotExist
异常.

这两个方法均接受可选关键字参数, 这些参数应该遵循上文中 "Field 查询" 中提到的格式.

注意如果遇到相同值的对象, 这些方法会使用 ID 字段进行检查. 这保证了没有一条记录会被跳过或重复记数.参阅lookup API sample model_ ,那里有一个完整的例子.

get_FOO_filename()

对一个 FileField 对象来说, 它自动拥有一个get_FOO_filename() 方法. 这里FOO
是字段名,它根据你的 MEDIA_ROOT 设置返回一个完整的路径名称.

注意 ImageField 技术上是FileField 的一个子类, 因此每个有ImageField
的 model 自动拥有此方法.

get_FOO_url()

含有 FileField 字段的每个对象自动拥有一个get_FOO_url() 方法,这里的FOO
是字段的名字. 该方法根据你的 MEDIA_URL 设置返回该文件的完整 URL ,如果MEDIA_URL 设置为空, 该方法返回一个空的字符串.

get_FOO_size()

含有 FileField 字段的每个对象自动拥有一个get_FOO_filename() 方法, 这里的FOO
是字段的名字. 该方法返回文件的长度(字节数).(在后台, Django 使用os.path.getsize.)

save_FOO_file(filename, raw_contents)

含有 FileField 字段的每个对象自动拥有一个get_FOO_filename() 方法, 这里的FOO
是字段的名字. 该方法使用给定的文件名将文件保存到文件系统.. 如果同目录下已经有同名文件存在,Django 会在文件名后添加一个下划线(扩展名之前)直到文件名有效为止(也就是如果加了下划线还重名,就再加....直到没有重名为止).

get_FOO_height() 和 get_FOO_width()

含有 ImageField 字段的每个对象自动拥有get_FOO_height() 和get_FOO_width()
方法, 这里的FOO 是字段的名字. 它们返回相应的图片高度和宽度(整数,以像素计).

原文地址: http://skandgjxa.blog.163.com/blog/static/141529820101018115135412/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: