玩转API
现在,让我们进入Python的交互式shell,玩转这些Django提供给你的API。 在cmd中使用如下命令来调用Python shell:
python manage.py shell
一旦你进入这个shell,请探索这些数据库 API:
In [1]: from polls.models import Question, Choice # Question暂时没有内容 In [2]: Question.objects.all() Out[2]: [] # django的时间模块,用timezone.now()可返回当前时间 In [3]: from django.utils import timezone In [4]: timezone.now() Out[4]: datetime.datetime(2016, 5, 11, 13, 4, 38, 930525, tzinfo=<UTC>) # 填写Question的question_text和pub_date两项内容 In [5]: q = Question(question_text="What's new?", pub_date=timezone.now()) # 保存 In [6]: q.save() # 返回ID In [7]: q.id Out[7]: 1 # 返回Question里面的question_text字段的值 In [8]: q.question_text Out[8]: "What's new?" # 返回Question里面的pub_date字段的内容 In [9]: q.pub_date Out[9]: datetime.datetime(2016, 5, 10, 2, 54, 11, 312500, tzinfo=<UTC>) # 改变question_text的内容并保存 In [10]: q.question_text = "What's up?" In [11]: q.save() # 可见,question_text的内容改变了 In [12]: q.question_text Out[12]: "What's up?" # 返回数据库中所有的Question对象 In [13]: Question.objects.all() Out[13]: [<Question: Question object>]
先等一下。<Question: Question object>对于这个对象是一个完全没有意义的表示。 让我们来修复这个问题,编辑Question模型(在polls/models.py文件中)并添加一个__str__()方法给Question和Choice:
from django.db import models class Question(models.Model): # ... def __str__(self): # __unicode__ on Python 2 return self.question_text class Choice(models.Model): # ... def __str__(self): # __unicode__ on Python 2 return self.choice_text
给你的模型添加__str__()方法很重要,不仅会使你自己在使用交互式命令行时看得更加方便,而且会在Django自动生成的管理界面中使用对象的这种表示。
然后为Question添加一个自定义的方法:
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.db import models from django.utils import timezone # Create your models here. class Question(models.Model): question_text = models.CharField(max_length=200) pub_date = models.DateTimeField('date published') def __str__(self): # __unicode__ on Python 2 return self.question_text def was_published_recently(self): return self.pub_date >= timezone.now() - datetime.timedelta(days=1) class Choice(models.Model): question = models.ForeignKey(Question) choice_text = models.CharField(max_length=200) votes = models.IntegerField(default=0) def __str__(self): # __unicode__ on Python 2 return self.choice_text
保存这些改动,然后通过python manage.py shell再次打开一个新的Python 交互式shell:
In [1]: from polls.models import Question,Choice # 添加__str__()方法后可以显示Question的内容了 In [2]: Question.objects.all() Out[2]: [<Question: What's up?>] # Django提供的数据库查询功能 # filter()用来筛选指定参数 In [3]: Question.objects.filter(id=1) Out[3]: [<Question: What's up?>] # 查询以'What'开头的记录 In [4]: Question.objects.filter(question_text__startswith='What') Out[4]: [<Question: What's up?>] # 查询pub_date值为本年的记录 In [5]: from django.utils import timezone In [6]: current_year = timezone.now().year In [7]: Question.objects.get(pub_date__year=current_year) Out[7]: <Question: What's up?> # 查询一个不存在的健会报错 In [8]: Question.objects.get(id=2) --------------------------------------------------------------------------- DoesNotExist Traceback (most recent call last) <ipython-input-8-e5ad49b3e3e3> in <module>() ----> 1 Question.objects.get(id=2) ………… DoesNotExist: Question matching query does not exist. # 通过主键(primary-key)查询 In [9]: Question.objects.get(pk=1) Out[9]: <Question: What's up?> # 获取主键(这里是ID)为1的记录 In [10]: q = Question.objects.get(pk=1) In [11]: q Out[11]: <Question: What's up?> # 执行自定义的was_published_recently方法 In [12]: q.was_published_recently() Out[12]: True # 返回choice_set,现在没有内容 In [13]: q.choice_set.all() Out[13]: [] # 写入三个choices In [14]: q.choice_set.create(choice_text='Not much', votes=0) Out[14]: <Choice: Not much> In [15]: q.choice_set.create(choice_text='The sky', votes=0) Out[15]: <Choice: The sky> In [16]: c = q.choice_set.create(choice_text='Just hacking again', votes=0) # Choice对象有一个API通道和Question对象关联,在这里question是Choice的外键 In [17]: c.question Out[17]: <Question: What's up?> # 反过来,也可以通过Question对象来访问Choice对象 In [18]: q.choice_set.all() Out[18]: [<Choice: Not much>, <Choice: The sky>, <Choice: Just hacking again>] # count()方法可以取得选项数量。 In [19]: q.choice_set.count() Out[19]: 3 # 可以透过API查询关联的表,用双下划线分割它们 In [20]: Choice.objects.filter(question__pub_date__year=current_year) Out[20]: [<Choice: Not much>, <Choice: The sky>, <Choice: Just hacking again>] In [21]: c = q.choice_set.filter(choice_text__startswith='Just hacking') In [22]: c.delete() Out[22]: (1, {'polls.Choice': 1})
更多关于模型关联的信息,请查看访问关联的对象。更多关于如何在这些API中使用双下划线来执行字段查询的信息,请查看 字段查询。更多关于数据库API的信息,请查看我们的 数据库API参考。