開始你的第一個Django應用【Python web實戰】

在這篇教程中,咱們將設置你的數據庫,建立你的第一個模型,並快速介紹Django的自動生成的管理站點。

ps注意不少人學Python過程當中會遇到各類煩惱問題,沒有人幫答疑容易放棄。爲此小編建了個Python全棧免費答疑.裙 :七衣衣九起起巴而五(數字的諧音)轉換下能夠找到了,不懂的問題有老司機解決裏面還有最新Python教程項目可拿,,一塊兒相互監督共同進步!python

數據庫配置

如今打開mysite/settings.py這是一個普通的python模塊,模塊變量表示Django的設定。mysql

默認狀況下,Django配置使用SQLite數據庫。若是你是數據庫初學者,或者只是感興趣想隨便試試Django,這是最簡單的選擇。SQLite包含在Python內,所以你不須要安裝任何其餘東西來支持你的數據庫。因此當你開始你的第一個真實項目時,你會想要使用一個更具擴展性的數據庫,好比PostgreSQL,以免數據庫切換引起的麻煩。sql

若是你但願使用其餘數據庫,安裝合適的數據庫綁定而且在DATABASES'default'項目中修改keys以匹配數據庫鏈接設置:shell

  • ENGINE
    好比 'django.db.backends.sqlite3', 'django.db.backends.postgresql', 'django.db.backends.mysql', or 'django.db.backends.oracle'。還有不少其餘後端也有提供。詳情請見數據庫

  • NAME
    你數據庫的名字。若是你使用SQLite,數據庫將是你計算機上的一個文件,這種狀況下,NAME應該是這個文件的完整絕對路徑,包括文件名。默認值os.path.join(BASE_DIR, 'db.sqlite3')將文件春處在項目目錄中。django

若是你不使用SQLite做爲你的數據庫,請務必添加USER, PASSWORD, 以及HOST。更多詳情後端

寫給其餘用戶的使用者
若是你在使用SQLite以外的數據庫,請確保你使用前已經建立了數據庫,請在你的數據庫裏使用CREATE DATABASE database_name;瀏覽器

同時確保mysite/settings.py擁有建立數據庫的權限。這樣就能夠自動建立一個在後面的教程中須要的測試數據庫。服務器

若是你正在使用SQLite,你不須要提早建立任何東西,數據庫文件會在必要的時候自動建立。網絡

當你開始編輯你的mysite/settings.py,設置你的TIME_ZONE爲你的時區。

另外,注意INSTALLED_APPS放在文件最上面,它承載着這個Django實例中全部活動的Django應用的名字,應用能夠被使用於多個項目中,你能夠打包分發他們讓別人在別的項目中使用。

默認狀況下,INSTALLED_APPS隨Django包含着幾個應用。

  • django.contrib.admin管理站點,你能當即使用上。
    -django.contrib.auth認證系統。
    -django.contrib.contenttypes內容類型的框架
    -django.contrib.sessions session框架
    -django.contrib.messages messaging框架
    -django.contrib.staticfiles 靜態文件管理

這些應用默認包括在內以方便開發者使用。

其中一些應用程序,須要至少一個數據庫表才能使用,所以咱們須要在數據庫中建立表,而後才能使用。請使用如下的命令:

python manage.py migrate

migrate命令查看INSTALLED_APPS的設置,並根據mysite/settings.py文件中的數據庫設置建立須要的數據庫表。若是你感興趣的話,打開數據庫命令行,輸入如下命令來看看Django幫你建立了什麼。

  • \dt(PostgreSQL),
  • SHOW TABLES;(MySQL),
  • .schema(SQLite),
  • SELECT TABLE_NAME FROM USER_TABLES;(Oracle)

寫給極簡主義者
正如咱們上面所說,咱們包含了默認應用爲了涵蓋常規使用,但並非每一個人都須要它們。若是你不須要,請在運行migrate以前,從INSTALLED_APPS中隨意把註釋掉或者刪掉對應的代碼。migrate命令只會運行INSTALLED_APPS中的應用。


建立模型

如今,咱們使用額外的元數據來定義你的模型(本質上就是你的數據庫佈局)。

模型的哲學
一個模型是關於您的數據的惟一的肯定的來源。它包含着您正在存儲的數據的基本字段和行爲。Django聽從DRY原則。咱們的目標是在一個地方定義您的數據模型而後自動地從中獲取數據。這就包括了遷移在裏面。舉個例子,不像Ruby on Rails,Django的遷移徹底源自您的數據模型,而且本質上只是Django能夠經過更新數據庫模式來匹配當前模型的歷史。

在咱們這個簡單的投票應用中,咱們會建立兩個模型:問題(question)和選擇(choice)。一個問題有一個問題內容和一個發佈時間。一個選擇有選擇的文本和投票計數器。每一個選擇都會和一個問題關聯。

這些概念經過簡單的python類就能夠表現出來。按照如下代碼,編輯你的polls/models.py文件。

polls/models.py
from django.db import models

class Question(models.Model): question_text = models.CharField(max_length=200) pub_date = models.DateTimeField('date published')

class Choice(models.Model): question = models.ForeignKey(Question, on_delete=models.CASCADE) choice_text = models.CharField(max_length=200) votes = models.IntegerField(default=0)

這些代碼很是明確。每一個模型經過一個繼承自django.db.models.Model的類來表示。每一個模型都有一些類變量,每一個變量都表示模型中的數據庫字段。

每一個字段經過實例中的一個字段類表示,好比CharField是字符字段,DateTimeField是時間字段。這會告訴Django每一個字段保存着什麼類型的數據。

每一個字段實例的名字(好比question_textpub_date)是字段的對機器友好的格式的名字,你之後能夠在你的Python代碼中使用這個值,你的數據庫也會用它做爲列名稱。

你可使用(可選的)第一個位置參數做爲指定的可讀的名稱。他能夠用於Django的幾個introspective(內省)部分,同時做爲文檔。若是沒有提供,則Django將使用機器可讀的名稱做爲名字。在這個例子中,咱們只對Question.pub_date定義了一個名字。對於其餘全部的字段都會默認使用本身的機器名做爲名字。

有些字段類有一些必須的參數要填。舉例,CharField要求你給出最大長度max_length。這不只會用在數據庫中,也會在驗證中使用,後面咱們會講到。

一個字段也能夠擁有不少可選的參數,好比咱們能夠看到,咱們班votes的默認值設成了0。

最後一點,注意關係是由外鍵定義的。這告訴Django,每個Choice都和只和一個問題相關。Django支持全部常見的數據庫關係:多對一,多對多,一對一。


激活模型(activating models)

這個簡單的模型告訴了Django不少信息。經過它,Django能夠作到:

  • 爲這個APP建立一個數據庫對象集合
  • 建立一個Python數據庫訪問API來訪問問題和選項的對象。

可是首先,咱們應該告訴咱們的項目,polls應用已經被安裝了。

Django哲學小課堂
Django的應用是可插拔的。您能夠在多個項目中使用某個應用程序,你能夠分發應用程序,由於他們並非和給定的Django安裝綁定的。

爲了把對應的應用包括進咱們的項目中,咱們須要在INSTALLED_APPS設置中添加對其配置類的引用。PollsConfig類在polls/app.py文件中,路徑是polls.apps.PollsConfig。編輯mysite/settings.py文件,添加路徑到INSTALLED_APPS設置中。

mysite/settings.py
INSTALLED_APPS = [ 'polls.apps.PollsConfig', 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', ]

如今Django已經知道要把polls應用囊括在內了,下面運行另外一條命令:

python manage.py makemigrations polls

你會看到相似下面的結果:

Migrations for 'polls': polls/migrations/0001_initial.py: -Creat model Choice -Create model Question -Add field question to choice

經過運行makemigrations,你能夠告訴Django你已經對你的model作出了一些改變,而且你但願這些改變能夠做爲migration存儲起來。(在如今的例子裏是建立了一個新的model)

Django經過Migration來存儲你的模型(也便是數據庫對象)的變化。他們只是硬盤上的一些文件。若是你想,你能夠爲你的新模型讀取一個Migration(遷移);也就是polls/migrations/0001_initial.py文件。不用擔憂,你並不須要每次Django做出改變都要讀取它們,可是若是你想手動調整Django如何改變內容,那麼它們是被設計爲能夠人爲編輯的。

有一個命令能夠幫你運行migration而且自動管理你的數據庫對象,也就是咱們稍後會介紹的migrate(遷移)。可是首先讓咱們看看migration會運行什麼樣的SQL。sqlmigrate命令接受遷移名稱,而且返回其SQL:

python manage.py sqlmigrate polls 0001

你應該會看到相似下面的結果

BEGIN;
--
-- *Create model Choice*
--
CREATE TABLE "polls_choice" ( "id" serial NOT NULL PRIMARY KEY, "choice_text" varchar(200) NOT NULL, "votes" integer NOT NULL );
--
-- *Create model Question*
--
CREATE TABLE "polls_question" ( "id" serial NOT NULL PRIMARY KEY, "question_text" varchar(200) NOT NULL, "pub_date" timestamp with time zone NOT NULL );
--
--*Add field question to choice*
--
ALTER TABLE "polls_choice" ADD COLUMN "question_id" integer NOT NULL;
ALTER TABLE "polls_choice" ALTER COLUMN "question_id" DROP DEFAULT;
CREATE INDEX "polls_choice_7aa0f6ee" ON "polls_choice" ("question_id");
ALTER TABLE "polls_choice" ADD CONSTRAINT "polls_choice_question_id_246c99a640fbbd72_fk_polls_question_id" FOREIGN KEY ("question_id") REFERENCES "polls_question" ("id") DEFERRABLE INITIALLY DEFERRED;
COMMIT;

注意:

  • 具體的輸出會根據你如何使用的數據庫而變化,上面的例子是根據PostgreSQL寫的。
  • 表的名字會根據應用的名字以及模型的小寫名自動生成(你能夠覆蓋這個行爲)
  • 主鍵會自動生成(你能夠覆蓋這個)
  • 按照慣例,django將"_id"附加到外鍵字段名稱。
  • 它根據你使用的數據庫量身打造,所以數據庫特定的字段類型好比auto_increment(MySQL), serial(PostgreSQL)或是integer primary key autoincrement (SQLite) 都會自動幫你處理。字段名的引用也一樣如此。
  • sqlmigrate命令並不會真的讓你的數據庫遷移,只是打印到屏幕上,讓你能夠看到Django須要什麼SQL。這對於檢查Django在幹什麼或者有須要SQL腳本更改的數據庫管理員很是有用。

若是你感興趣,你還能夠運行python manage.py check,這會不進行任何遷移,不接觸數據庫來檢查你的項目有沒有什麼問題。

如今,再次運行migrate建立你的模型吧。

`$ python manage.py migrate
Operations to perform:
Apply all migrations: admin, auth, contenttypes, polls, sessions

Running migrations:
Rendering model states... DONE
Applying polls.0001_initial... OK`

migrate 命令接收全部未應用的遷移(Django經過一個叫作django_migrations的特殊表聊跟蹤哪些遷移被應用了)並根據數據庫運行他們。本質上是將你對模型的更改與數據庫對象進行同步。

遷移很是強大,他可讓你一邊建設你的項目,一邊慢慢地改變你的數據庫,並且不用刪除你的數據庫或者表,或者建立一個新的。它專門用於實時升級數據庫,而不會丟失數據。咱們將在本教程的後續部分中更深刻地介紹它們,可是如今,請記住進行模型更改的三步指南:

  • 更改你的模型(在 models.py 中)。
  • 運行 python manage.py makemigrations 來建立這些更改的遷移
  • 運行 python manage.py migrate 將這些更改應用於數據庫。

Django有單獨的命令來製做和應用遷移的緣由是由於您能夠提交遷移到版本控制系統並將其發送到您的應用程序; 它們不只可使您的開發更容易,並且還能夠被其餘開發人員和生產中使用。

請閱讀 django-admin文檔,瞭解有關 manage.py 能夠執行的操做的完整信息。


玩轉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也沒問題, 只要將DJANGO_SETTINGS_MODULE
環境變量設置給mysite.settings,打開一個普通的python shell,而後設置Django:
>>>import django
>>>django.setup()

若是這引起了一個AttributeError,你也許用的Django版本不是1.11,請更換不一樣版本的教程或者升級你的Django。

你必須在manage.py所在的目錄下運行Python,或者保證目錄在Python路徑上,import mysite才能正常工做。

更多相關信息,請參考django-admin documentation

進入了shell後,咱們來看看database API:

>>> from polls.models import Question, Choice # Import the model classes we just wrote.

# No questions are in the system yet.
>>> Question.objects.all()
<QuerySet []>

# 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=<UTC>)

# 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()
<QuerySet [<Question: Question object>]>

等一下!<>徹底是一個沒有任何幫助的表達,讓咱們編輯問題模型(在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()
<QuerySet [<Question: What's up?>]>

# Django provides a rich database lookup API that's entirely driven by
# keyword arguments.
>>> Question.objects.filter(id=1)
<QuerySet [<Question: What's up?>]>
>>> Question.objects.filter(question_text__startswith='What')
<QuerySet [<Question: What's up?>]>

# 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)
<Question: What's up?>

# 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)
<Question: What's up?>

# 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()
<QuerySet []>

# Create three choices.
>>> 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 objects have API access to their related Question objects.
>>> c.question
<Question: What's up?>

# And vice versa: Question objects get access to Choice objects.
>>> q.choice_set.all()
<QuerySet [<Choice: Not much>, <Choice: The sky>, <Choice: Just hacking again>]>
>>> 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)
<QuerySet [<Choice: Not much>, <Choice: The sky>, <Choice: Just hacking again>]>

# Let's delete one of the choices. Use delete() for that.
>>> c = q.choice_set.filter(choice_text__startswith='Just hacking')
>>> c.delete()

有關模型關係的更多信息,請參閱訪問 相關文檔. 有關如何使用雙下劃線經過API執行字段查找的更多信息,請參閱 Field lookups. 有關數據庫API的完整詳細信息,請參閱咱們的 Database API reference.


Django Admin介紹

"Django的哲學"小課堂
Django管理站點是爲你的員工或者客戶的簡單的添加,更改,刪除這些繁瑣工做而設計的。Django管理站點會徹底自動生成模型的管理站。

Django當年建立於新聞編輯室,爲內容管理而生的,「內容發佈者」和「公共」網站之間的界限很是明確。網站管理人員使用該系統添加新聞故事,事件,體育比分等,該內容顯示在公共站點上。 Django解決了爲站點管理員建立統一界面來編輯內容的問題。

這個管理站點不打算由網站訪問者使用。這是網站經理。

建立一個管理員用戶

首先,咱們須要建立一個用戶來登陸管理站點。使用下面的命令:
python manage.py createsuperuser
輸入你想要的用戶名
Username: admin
輸入郵箱地址
Email address: admin@example.com
最後輸入你的密碼兩次。
Password: **********
Password (again): *********
Superuser created successfully.

開啓你的開發服務器

django管理站點會自動啓動,咱們只要啓動開發服務器就能夠來一塊兒探索它了。
使用python manage.py runserver開啓服務器。
如今打開一個瀏覽器,而且去/admin/-例如http://127.0.0.1:8000/admin/你應該會看到Django administration的登陸界面。

進入admin管理站點。
總結:不少人學Python過程當中會遇到各類煩惱問題,沒有人幫答疑容易放棄。爲此小編建了個Python全棧免費答疑.裙 :七衣衣九起起巴而五(數字的諧音)轉換下能夠找到了,不懂的問題有老司機解決裏面還有最新Python教程項目可拿,,一塊兒相互監督共同進步!

本文的文字及圖片來源於網絡加上本身的想法,僅供學習、交流使用,不具備任何商業用途,版權歸原做者全部,若有問題請及時聯繫咱們以做處理。

相關文章
相關標籤/搜索