玩转API
现在,我们一起进入交互式的Python shell,并使用Django提供的免费API。要调用Python shell,请使用一下命令:
python manage.py shell
我们没有简单的输入python而是使用这个命令,因为manage.py设置了DJANGO_SETTINGS_MODULE环境变量,这给了Django提供了你的mysite/settings.py文件的Python导入路径。
绕过manage.py
如果你不想用manage.py也没问题, 只要将mysite.settings,打开一个普通的python shell,然后设置Django:
>>>import django
>>>django.setup()
如果这引发了一个AttributeError,你也许用的Django版本不是1.11,请更换不同版本的教程或者升级你的Django。
你必须在manage.py所在的目录下运行Python,或者保证目录在Python路径上,import mysite才能正常工作。
更多相关信息,请参考>>> from polls.models import Question, Choice # Import the model classes we just wrote.
# No questions are in the system yet.
>>> Question.objects.all()
# Create a new Question.
# Support for time zones is enabled in the default settings file, so
# Django expects a datetime with tzinfo for pub_date. Use timezone.now()
# instead of datetime.datetime.now() and it will do the right thing.
>>> from django.utils import timezone
>>> q = Question(question_text="What's new?", pub_date=timezone.now())
# Save the object into the database. You have to call save() explicitly.
>>> q.save()
# Now it has an ID. Note that this might say "1L" instead of "1", depending
# on which database you're using. That's no biggie; it just means your
# database backend prefers to return integers as Python long integer
# objects.
>>> q.id
1
# Access model field values via Python attributes.
>>> q.question_text
"What's new?"
>>> q.pub_date
datetime.datetime(2012, 2, 26, 13, 0, 0, 775217, tzinfo=)
# Change values by changing the attributes, then calling save().
>>> q.question_text = "What's up?"
>>> q.save()
# objects.all() displays all the questions in the database.
>>> Question.objects.all()
]>
等一下!<>完全是一个没有任何帮助的表达,让我们编辑问题模型(在polls/models.py文件中)来解决这个问题。然后添加__str__()方法到Question和Choice。
polls/models.py
from django.db import models
from django.utils.encoding import python_2_unicode_compatible
@python_2_unicode_compatible # only if you need to support Python 2
class Question(models.Model): def __str__(self): return self.question_text
@python_2_unicode_compatible # only if you need to support Python 2
class Choice(models.Model): def __str__(self): return self.choice_text
__str__()方法的添加是很重要的,不光是为了你自己处理交互提示的方便,也是因为对象的展示是通过Django的自动生成admin的。
注意这些都是普通Python方法,现在我们添加一个自定义方法,为了演示使用。
polls/models.py
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和django.utils import timezone可以分别在django.utils.timezone中引用Python的标准datetime模块和Django的时区相关实用程序。如果您不熟悉Python中的时区处理,您可以在python manage.py shell启动一个新的Python shell:
>>> from polls.models import Question, Choice
# Make sure our __str__() addition worked.
>>> Question.objects.all()
]>
# Django provides a rich database lookup API that's entirely driven by
# keyword arguments.
>>> Question.objects.filter(id=1)
]>
>>> Question.objects.filter(question_text__startswith='What')
]>
# Get the question that was published this year.
>>> from django.utils import timezone
>>> current_year = timezone.now().year
>>> Question.objects.get(pub_date__year=current_year)
# Request an ID that doesn't exist, this will raise an exception.
>>> Question.objects.get(id=2)
Traceback (most recent call last):
...
DoesNotExist: Question matching query does not exist.
# Lookup by a primary key is the most common case, so Django provides a
# shortcut for primary-key exact lookups.
# The following is identical to Question.objects.get(id=1).
>>> Question.objects.get(pk=1)
# Make sure our custom method worked.
>>> q = Question.objects.get(pk=1)
>>> q.was_published_recently()
True
# Give the Question a couple of Choices. 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
# (e.g. a question's choice) which can be accessed via the API.
>>> q = Question.objects.get(pk=1)
# Display any choices from the related object set -- none so far.
>>> q.choice_set.all()
# Create three choices.
>>> 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 objects have API access to their related Question objects.
>>> c.question
# And vice versa: Question objects get access to Choice objects.
>>> q.choice_set.all()
, , ]>
>>> q.choice_set.count()
3
# The API automatically follows relationships as far as you need.
# Use double underscores to separate relationships.
# This works as many levels deep as you want; there's no limit.
# Find all Choices for any question whose pub_date is in this year
# (reusing the 'current_year' variable we created above).
>>> Choice.objects.filter(question__pub_date__year=current_year)
, , ]>
# Let's delete one of the choices. Use delete() for that.
>>> c = q.choice_set.filter(choice_text__startswith='Just hacking')
>>> c.delete()
有关模型关系的更多信息,请参阅访问