接下來,我們進(jìn)入 Python 的交互式 shell 中玩轉(zhuǎn) Django 提供的 API 。使用以下命令調(diào)用Python shell:
python manage.py shell
我們當(dāng)前使用的環(huán)境不同于簡單的輸入 “python” 進(jìn)入的 shell 環(huán)境, manage.py 文件設(shè)置了 DJANGO_SETTINGS_MODULE環(huán)境變量,該變量給定了 Django 需要導(dǎo)入的 mysite/settings.py 文件所在路徑。
注:如果確實不想使用 manage.py 也可以,只需要設(shè)置環(huán)境變量DJANGO_SETTINGS_MODULE的值為mysite.settings,啟用Python shell 并輸入以下命令即可:
import djangodjango.setup()此處需注意應(yīng)在與 manage.py 文件所在同一目錄下運(yùn)行 python ( 或確保目錄在 Python path 下)
進(jìn)入shell中后,就可以開始探索 database API了
>>> from polls.models import Question, Choice # 導(dǎo)入剛創(chuàng)建的模塊類>>> Question.objects.all()[]# 創(chuàng)建一個新的Question# 默認(rèn)配置文件中時區(qū)支持是啟用的,因此 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())# 將對象保存到數(shù)據(jù)庫中,此處應(yīng)調(diào)用save() 方法>>> q.save()# 現(xiàn)在對象有了一個 ID. 此處注意有可能會顯示 "1L" 而不是 "1", 這取決于你正使用的數(shù)據(jù)庫# 這無關(guān)緊要,僅僅表明你的數(shù)據(jù)庫后端更偏向于返回 integers 作為 Python 的 long integer 對象>>> q.id1# 通過 Python 屬性訪問字段值>>> q.question_text"What's new?">>> q.pub_datedatetime.datetime(2014, 9, 13, 6, 31, 27, 704000, tzinfo=<UTC>)
# 通過改變屬性來改變值, 然后調(diào)用 save().>>> q.question_text = "What's up?">>> q.save()# objects.all() 用以打印出所有在數(shù)據(jù)庫中的 question.>>> Question.objects.all()[<Question: Question object>]
注意:<Question: Question object> 這樣的對象顯示方式是毫無意義的。
為了轉(zhuǎn)換成我們看得懂的顯示方式,此處可以通過修改 Question 這個model (polls/models.py 文件中)并為 Question 和 Choice 都添加上一個__str__()方法:
from django.db import modelsclass Question(models.Model): # ... def __str__(self): #Python 2.x 用 __unicode__ return self.question_textclass 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 有一個默認(rèn)的__str__()方法會調(diào)用__unicode__()方法將結(jié)果轉(zhuǎn)換成UTF-8編碼的字符串,這就意味著 unicode(p)將返回一個Unicode編碼的字符串,而str(p)將返回一個UTF-8編碼字符串。Python則相反:object 擁有一個__unicode__ 方法調(diào)用__str__將結(jié)果轉(zhuǎn)變?yōu)?ASCII 字符串,這極容易造成混淆。
如果上面的這些讓你感覺到混亂,那么推薦使用Python 3.x版本。
接下來嘗試著自定義一個方法
import datetimefrom django.db import modelsfrom django.utils import timezoneclass 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 的標(biāo)準(zhǔn)庫的 datetime 模塊和 Django 的 django.utils.timezone 中的 time-zone-related 實用工具 。
保存以上更改并且再次運(yùn)行 python manage.py shell 以開啟一個新的 Python shell
>>> from polls.models import Question, Choice
# 確認(rèn)下添加的 __str__() 正常運(yùn)行.>>> Question.objects.all()[<Question: What's up?>]# Django 提供了一個豐富的完全由關(guān)鍵字驅(qū)動的數(shù)據(jù)庫查詢 API >>> Question.objects.filter(id=1)[<Question: What's up?>]>>> Question.objects.filter(question_text__startswith='What')[<Question: What's up?>]# 獲取在今年內(nèi)發(fā)布的 Question>>> from django.utils import timezone>>> current_year = timezone.now().year>>> Question.objects.get(pub_date__year=current_year)<Question: What's up?># 請求一個不存在的 ID ,然后將引發(fā)異常.>>> Question.objects.get(id=2)Traceback (most recent call last): ...DoesNotExist: Question matching query does not exist.# 根據(jù)主鍵查詢是一種比較常見的方式, 因此 Django 提供了一個精確查找主鍵的快捷方式# 以下內(nèi)容等同于 Question.objects.get(id=1).>>> Question.objects.get(pk=1)<Question: What's up?># 確認(rèn)下我們自定義的方法正常運(yùn)行.>>> q = Question.objects.get(pk=1)>>> q.was_published_recently()True# 給 Question 設(shè)置一些 Choice. 創(chuàng)建一個新的 Choice 對象,執(zhí)行 INSERT 語句后,
# 添加 choice 到可用的 choices 集合然后返回一個新的 Choice 對象.
# Django 創(chuàng)建了一個可以通過 API 訪問的保存外鍵關(guān)聯(lián)的集合(如 question 的 choice)>>> q = Question.objects.get(pk=1)# 從關(guān)聯(lián)對象集合中顯示所有 choice -- 當(dāng)前為空.>>> q.choice_set.all()[]# 創(chuàng)建三個 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 對象擁有訪問與它們關(guān)聯(lián)的 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 會自動連續(xù)關(guān)聯(lián),可以使用雙下劃線來隔離關(guān)聯(lián)
# 需要多少層的關(guān)聯(lián)就可以有多少層的關(guān)聯(lián),沒有任何限制# 找出所有 pub_date 在今年的與 question 有關(guān)聯(lián)的 Choice# (重復(fù)使用我們之前創(chuàng)建的的變量 '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/
未完待續(xù)。。。
新聞熱點
疑難解答