现在让我们进入交互式 Python 命令行,尝试一下 Django 为你创建的各种 API。通过以下命令打开 Python 命令行:
python manage.py shell
或者我们可以打开Pycharm的Tool->Python Console
Python 3.7.3 (v3.7.3:ef4ec6ed12, Mar 25 2019, 22:22:05) [MSC v.1916 64 bit (AMD64)] on win32
Django 2.2.1
引入上一篇中我们创建的Choice和Question模型类:
>>> from polls.models import Choice, Question
查询Question中的内容,目前还是空:
>>> Question.objects.all()
创建一个新的Question,在Django中建议使用timezone.now()而不是datetime.datetime.now(),因此引入timezone:
>>> from django.utils import timezone
>>> q = Question(question_text="What's new?", pub_date=timezone.now())
使用save(),保存刚刚创建的Question进数据库:
>>> q.save()
ID是自动生成的,q.id可以查询当前的id号:
>>> q.id
1
通过python属性访问模型字段值:
Access model field values via Python attributes.
>>> q.question_text
"What's new?"
>>> q.pub_date
datetime.datetime(2019, 5, 19, 16, 23, 13, 320097)
>>> q.question_text = "What's up?"
>>> q.save()
objects.all()显示数据库中所有的对象:
>>> Question.objects.all()
]>
但是输出结果
from django.db import models
class Question(models.Model):
question_text = models.CharField(max_length=200)
pub_date = models.DateTimeField('date published')
def __str__(self):
return self.question_text
class Choice(models.Model):
question = models.ForeignKey(Question, on_delete=models.CASCADE)
choice_text = models.CharField(max_length=200)
votes = models.IntegerField(default=0)
def __str__(self):
return self.choice_text
重新打开Python Console,再次查询,确认我们加的__str __() 生效了:
>>> from polls.models import Choice, Question
>>> Question.objects.all()
]>
Django提供了丰富的数据库查找API,它完全由关键字参数驱动。
>>> Question.objects.filter(id=1)
]>
>>> Question.objects.filter(question_text__startswith='What')
]>
获取今年发布的问题:
>>> from django.utils import timezone
>>> current_year = timezone.now().year
>>> Question.objects.get(pub_date__year=current_year)
如果请求不存在的ID,将引发异常:
>>> Question.objects.get(id=2)
Traceback (most recent call last):
...
polls.models.Question.DoesNotExist: Question matching query does not exist.
通过主键查找是最常见的情况,因此Django提供了主键精确查找的快捷方式,以下内容与Question.objects.get(id = 1)相同。
>>> Question.objects.get(pk=1)
给模型增加 __ str__() 方法是很重要的,这不仅仅能给你在命令行里使用带来方便,Django 自动生成的 admin 里也使用这个方法来表示对象。
注意:这些都是常规的 Python方法。让我们添加一个自定义的方法was_published_recently,这只是为了演示:
import datetime
from django.db import models
from django.utils import timezone
class Question(models.Model):
question_text = models.CharField(max_length=200)
pub_date = models.DateTimeField('date published')
def __str__(self):
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, on_delete=models.CASCADE)
choice_text = models.CharField(max_length=200)
votes = models.IntegerField(default=0)
def __str__(self):
return self.choice_text
重新连接,查看我们新加的自定义方法是否生效:
>>> from polls.models import Choice, Question
>>> q = Question.objects.get(pk=1)
>>> q.was_published_recently()
True
给提出的问题添加几个选择。
The create call constructs a new Choice object, does the INSERT statement, adds the choice to the set of available choices and returns the new Choice object. Django creates a set to hold the “other side” of a ForeignKey relation
(例如问题的选择)可以通过API访问。
>>> q = Question.objects.get(pk=1)
显示q对象(主键为1)对应的choice,目前为空。
>>> q.choice_set.all()
创建三个Choice:
>>> q.choice_set.create(choice_text='Not much', votes=0)
>>> q.choice_set.create(choice_text='The sky', votes=0)
>>> c = q.choice_set.create(choice_text='Just hacking again', votes=0)
Choice对象具有对其相关Question对象的API访问权限。
>>> c.question
反之亦然:Question 对象可以访问Choice对象。
>>> q.choice_set.all()
, , ]>
>>> q.choice_set.count()
3
API会根据您的需要自动跟踪关系,使用双下划线来分隔关系,这可以像你想要的那样深入多层次; 没有限制。
查找pub_date在今年的任何问题的所有选择(可重用我们上面创建的’current_year’变量)。
>>> from django.utils import timezone
>>> current_year = timezone.now().year
>>> Choice.objects.filter(question__pub_date__year=current_year)
, , ]>
使用delete()删除其中一个choice。
>>> c = q.choice_set.filter(choice_text__startswith='Just hacking')
>>> c.delete()