Django1.7学习(二)

7.玩转API

接下来,我们进入 Python 的交互式 shell 中玩转 Django 提供的 API 。使用以下命令调用Python shell:

python manage.py shell

我们当前使用的环境不同于简单的输入 “python” 进入的 shell 环境, manage.py 文件设置了 DJANGO_SETTINGS_MODULE环境变量,该变量给定了 Django 需要导入的 mysite/settings.py 文件所在路径。

注:如果确实不想使用 manage.py 也可以,只需要设置环境变量DJANGO_SETTINGS_MODULE的值为mysite.settings,启用Python shell 并输入以下命令即可:

import django django.setup()

此处需注意应在与 manage.py 文件所在同一目录下运行 python ( 或确保目录在 Python path 下)

进入shell中后,就可以开始探索 database API了

>>> from polls.models import Question, Choice   # 导入刚创建的模块类



>>> Question.objects.all()

[]



# 创建一个新的Question

# 默认配置文件中时区支持是启用的,因此 Django 希望为 pub_date 获取一个带 tzinfo 的 datetime

# 此处使用 timezone.now() 来替代 datetime.datetime.now() 以获取正确的值

>>> from django.utils import timezone

>>> q = Question(question_text="What's new?",pub_date=timezone.now())



# 将对象保存到数据库中,此处应调用save() 方法

>>> q.save()



# 现在对象有了一个 ID. 此处注意有可能会显示 "1L" 而不是 "1", 这取决于你正使用的数据库

# 这无关紧要,仅仅表明你的数据库后端更偏向于返回 integers 作为 Python 的 long integer 对象

>>> q.id

1



# 通过 Python 属性访问字段值

>>> q.question_text

"What's new?"

>>> q.pub_date

datetime.datetime(2014, 9, 13, 6, 31, 27, 704000, tzinfo=<UTC>)

# 通过改变属性来改变值, 然后调用 save(). >>> q.question_text = "What's up?" >>> q.save() # objects.all() 用以打印出所有在数据库中的 question. >>> Question.objects.all() [<Question: Question object>]

注意:<Question: Question object> 这样的对象显示方式是毫无意义的。

为了转换成我们看得懂的显示方式,此处可以通过修改 Question 这个model (polls/models.py 文件中)并为 Question 和 Choice 都添加上一个__str__()方法:

from django.db import models



class Question(models.Model):

    # ...

    def __str__(self):              #Python 2.x 用 __unicode__ 

        return self.question_text



class Choice(models.Model):

    # ...

    def __str__(self):              #Python 2.x 用 __unicode__

        return self.choice_text

为 models 添加__str__()方法是很重要的,不只能让自己在处理交互式提示时更加清晰,同时在 Django 自动生成的后台管理界面中也会用到

__str__ 还是 __unicode__?

如果使用的是Python 3.x 版本,很简单,直接使用 __str__()

如果使用的是Python 2.x 版本,则需要定义 __unicode__()方法来返回unicode值。Django 的 models 有一个默认的__str__()方法会调用__unicode__()方法将结果转换成UTF-8编码的字符串,这就意味着 unicode(p)将返回一个Unicode编码的字符串,而str(p)将返回一个UTF-8编码字符串。Python则相反:object 拥有一个__unicode__ 方法调用__str__将结果转变为 ASCII 字符串,这极容易造成混淆。

如果上面的这些让你感觉到混乱,那么推荐使用Python 3.x版本。

 接下来尝试着自定义一个方法

import datetime



from django.db import models

from django.utils import timezone



class Question(models.Model):

    # ...

    def was_published_recently(self):

        return self.pub_date >= timezone.now() - datetime.timedelta(days=1)

增加了 import datetime 和 from django.utils import timezone, 分别是为了引用 Python 的标准库的 datetime 模块和 Django 的 django.utils.timezone 中的 time-zone-related 实用工具 。

保存以上更改并且再次运行 python manage.py shell 以开启一个新的 Python shell

>>> from polls.models import Question, Choice

#
确认下添加的 __str__() 正常运行. >>> Question.objects.all() [<Question: What's up?>] # Django 提供了一个丰富的完全由关键字驱动的数据库查询 API >>> Question.objects.filter(id=1) [<Question: What's up?>] >>> Question.objects.filter(question_text__startswith='What') [<Question: What's up?>] # 获取在今年内发布的 Question >>> from django.utils import timezone >>> current_year = timezone.now().year >>> Question.objects.get(pub_date__year=current_year) <Question: What's up?> # 请求一个不存在的 ID ,然后将引发异常. >>> Question.objects.get(id=2) Traceback (most recent call last): ... DoesNotExist: Question matching query does not exist. # 根据主键查询是一种比较常见的方式, 因此 Django 提供了一个精确查找主键的快捷方式 # 以下内容等同于 Question.objects.get(id=1). >>> Question.objects.get(pk=1) <Question: What's up?> # 确认下我们自定义的方法正常运行. >>> q = Question.objects.get(pk=1) >>> q.was_published_recently() True # 给 Question 设置一些 Choice. 创建一个新的 Choice 对象,执行 INSERT 语句后,
# 添加 choice 到可用的 choices 集合然后
返回一个新的 Choice 对象.
# Django 创建了一个可以通过 API 访问的保存外键关联的集合(如 question 的 choice)
>>> q = Question.objects.get(pk=1) # 从关联对象集合中显示所有 choice -- 当前为空. >>> q.choice_set.all() [] # 创建三个 choice. >>> q.choice_set.create(choice_text='Not much', votes=0) <Choice: Not much> >>> q.choice_set.create(choice_text='The sky', votes=0) <Choice: The sky> >>> c = q.choice_set.create(choice_text='Just hacking again', votes=0) # Choice 对象拥有访问与它们关联的 Question 对象的 API >>> c.question <Question: What's up?> # 反之亦然: Question 对象也可以访问 Choice 对象. >>> q.choice_set.all() [<Choice: Not much>, <Choice: The sky>, <Choice: Just hacking again>] >>> q.choice_set.count() 3 # 只要需要 API 会自动连续关联可以使用双下划线来隔离关联
# 需要多少层的关联就可以有多少层的关联
,没有任何限制 # 找出所有 pub_date 在今年的与 question 有关联的 Choice # (重复使用我们之前创建的的变量 'current_year') >>> Choice.objects.filter(question__pub_date__year=current_year) [<Choice: Not much>, <Choice: The sky>, <Choice: Just hacking again>] # 用 delete() 来删除 choices 的其中一个. >>> c = q.choice_set.filter(choice_text__startswith='Just hacking') >>> c.delete()

 参考:https://docs.djangoproject.com/en/1.7/intro/tutorial01/

未完待续。。。

你可能感兴趣的:(django)