Django tutorial(3) 【翻译】编写第一个Django app,第三部分——玩转模型层的API

来源:互联网 发布:淘宝如何筛选发货地 编辑:程序博客网 时间:2024/05/21 09:01

玩转模型层的API

现在,让我们进入Python shell中玩转Django为我们提供了的免费的API。使用下面的命令运行Python shell:

  python manage.py shell

现在你已经进入到shell中了,研究一下这些数据库的API吧:


>>> from mysite.polls.models import Poll, Choice # Import the model classes we just wrote.

# 现在系统中还没有polls。
>>> Poll.objects.all()
[]

# 创建一个新的Poll。
>>> import datetime
>>> p = Poll(question="What's up?", pub_date=datetime.datetime.now())

# 把这个对象保存到数据库中。你需要显式调用save()方法。
>>> p.save()

# 现在它有一个ID了。它有可能是"1L"或者"1",
#
这完全取决于你正在使用的数据库。这不是什么大问题;
#
它只不过是返回一个Python长整型对象的数字而已。
>>> p.id
1

# 通过Python的属性值访问数据库的列。
>>> p.question
"What's up?"
>>> p.pub_date
datetime.datetime(
2007, 7, 15, 12, 00, 53)

# 通过Python属性值修改数据库的值,并调用save()方法。
>>> p.pub_date = datetime.datetime(2007, 4, 1, 0, 0)
>>> p.save()

# objects.all()显示数据库中所有的polls。
>>> Poll.objects.all()
[
<Poll: Poll object>]

 

等下。<Poll: Poll object> 根本就不能帮助我们描述这个对象。让我们编辑polls模型来修正它(在polls/models.py文件中),给Poll和Choice方法各添加一个__unicode__()方法。

class Poll(models.Model):
#
def __unicode__(self):
return self.question

class Choice(models.Model):
#
def __unicode__(self):
return self.choice

 

如果__unicode__()看起来没有执行

如果你给你的models添加的__unicode__()方法并没有看到它们的描述信息有变化,你很可能正在使用的是旧版本的Django。(本教程是面向Django最新的开发版写的。)旧版使用__str__()方法。

给你的models添加__unicode__()方法是件很重要的事情,它不仅仅是为了使你在提示窗口中得到智能的提示,更是因为对象的描述在Django自动生成的admin中会使用到。

为什么是__unicode__()而不是django.db.models.Model.__str__()?

如果你熟悉Python的话,你可能习惯于给你的类添加django.db.models.Model.__str__()方法而不是__unicode__()方法。我们这里之所以使用__unicode__()是因为Django models默认是处理Unicode的。所有保存在你的数据库中的数据在返回的时候都转换为Unicode。

Django models有一个默认的方法django.db.models.Model.__str__(),它会调用__unicode__()方法并返回一个UTF-8格式的字符串。也就是说,unicode(p)将会返回一个Unicode的字符串,而str(p)将会返回一个普通的字符串,它的字符是被编码为UTF-8的。

如果你还不理解的话,你只要记得给你的models添加__unicode__()方法就行了。如果运气不背的话,事情就会如你所愿的执行。

注意下面这些普通的Python方法。让我们添加一些自定义的方法,就如例子所演示的:

 

import datetime
#
class Poll(models.Model):
#
def was_published_today(self):
return self.pub_date.date() == datetime.date.today()

 

注意到,我添加了import datetime来引用Python的标准datetime模块。

让我们再次运行python manage.py shell来进入Python shell吧:

 


>>> from mysite.polls.models import Poll, Choice

# 确认我们添加的__unicode__()方法能够正确执行
>>> Poll.objects.all()
[
<Poll: What's up?>]

# Django 提供了丰富的数据库检索API,它完全是使用关键字参数运行。
>>> Poll.objects.filter(id=1)
[
<Poll: What's up?>]
>>> Poll.objects.filter(question__startswith='What')
[
<Poll: What's up?>]

# 返回年份是2007年的poll。当然了,你也可以检索其它年份,
#
只需要做适当的修改。
>>> Poll.objects.get(pub_date__year=2007)
<Poll: What's up?>

>>> Poll.objects.get(id=2)
Traceback (most recent call last):

DoesNotExist: Poll matching query does
not exist.

# 根据主键检索是最常用的, 因此Django提供了更便捷的
#
使用主键检索的方法。
#
下面的语句和Poll.objects.get(id=1)是等效的。
>>> Poll.objects.get(pk=1)
<Poll: What's up?>

# 确认我们自定义的方法是否能执行
>>> p = Poll.objects.get(pk=1)
>>> p.was_published_today()
False

# 给Poll更多的选择。create方法构建一个新的choice对象,
#
执行INSERT命令, 把choice添加到变量choices中,
#
返回这个新创建的Choice对象。
>>> p = Poll.objects.get(pk=1)
>>> p.choice_set.create(choice='Not much', votes=0)
<Choice: Not much>
>>> p.choice_set.create(choice='The sky', votes=0)
<Choice: The sky>
>>> c = p.choice_set.create(choice='Just hacking again', votes=0)

# Choice对象拥有访问它们关联的Poll对象的API。
>>> c.poll
<Poll: What's up?>

# 反之亦然:Poll对象能够访问Choice对象。
>>> p.choice_set.all()
[
<Choice: Not much>, <Choice: The sky>, <Choice: Just hacking again>]
>>> p.choice_set.count()
3

# 这些API是在你需要使用的时候自动关联的。
#
使用两个下划线来分开关联
#
它能作用到不同的层面;它是没有限制的。
#
检索所有的Choices的所有pub_date是在2007年的poll。
>>> Choice.objects.filter(poll__pub_date__year=2007)
[
<Choice: Not much>, <Choice: The sky>, <Choice: Just hacking again>]

# 让我们删除所有的choices。使用delete()方法来完成它。
>>> c = p.choice_set.filter(choice__startswith='Just hacking')
>>> c.delete()
原创粉丝点击