Django-編寫你的第一個Django應用程式3
文章目錄
資料庫設定
開啟mysite/settings.py.這是一個普通的Python模組,其中的模組級變數代表Django設定。 預設情況下,配置使用SQLite。 如果您希望使用其他資料庫,請安裝相應的資料庫繫結,並在DATABASES '預設’專案中更改以下鍵以匹配您的資料庫連線設定:
- ENGINE – 下面中的任一一種’django.db.backends.sqlite3’, ‘django.db.backends.postgresql’, ‘django.db.backends.mysql’, 或’django.db.backends.oracle’。 這四種是官方支援的資料庫,其他後端也可以通過第三方支援來使用,具體檢視https://docs.djangoproject.com/en/2.1/ref/databases/#third-party-notes。
- NAME –你資料庫的名稱 如果你使用的是的SQLite, 資料庫就是你電腦上的一個檔案; 在這種情況下, NAME 應該設定為一個完整的絕對路徑, 包括檔名。預設值是os.path.join(BASE_DIR, ‘db.sqlite3’),將會把檔案儲存在您的專案目錄中。 如果您不使用SQLite作為資料庫,則必須新增其他設定,例如USER,PASSWORD和HOST。
在編輯mysite/settings.py時,將TIME_ZONE設定為您的時區。
另外,請注意檔案頂部的INSTALLED_APPS設定。 它包含在此Django例項中啟用的所有Django應用程式的名稱。 應用程式可以用於多個專案,您可以打包並分發這些應用程式以供他人在其專案中使用。
預設情況下,INSTALLED_APPS包含以下應用程式,這些應用程式都是Django附帶的:
- django.contrib.admin - admin網站。 你會很快使用它。
- django.contrib.auth - 認證系統。
- django.contrib.contenttypes - 內容型別的框架。
- django.contrib.sessions - 會話框架。
- django.contrib.messages - 一個訊息框架。
- django.contrib.staticfiles - 管理靜態檔案的框架。
其中一些應用程式至少使用了一個數據庫表,所以我們需要在資料庫中建立表格,然後才能使用它們。 為此,請執行以下命令:
$ python manage.py migrate
python3 manage.py migrate
Operations to perform:
Apply all migrations: admin, auth, contenttypes, sessions
Running migrations:
Applying contenttypes.0001_initial... OK
Applying auth.0001_initial... OK
Applying admin.0001_initial... OK
Applying admin.0002_logentry_remove_auto_add... OK
Applying admin.0003_logentry_add_action_flag_choices... OK
Applying contenttypes.0002_remove_content_type_name... OK
Applying auth.0002_alter_permission_name_max_length... OK
Applying auth.0003_alter_user_email_max_length... OK
Applying auth.0004_alter_user_username_opts... OK
Applying auth.0005_alter_user_last_login_null... OK
Applying auth.0006_require_contenttypes_0002... OK
Applying auth.0007_alter_validators_add_error_messages... OK
Applying auth.0008_alter_user_username_max_length... OK
Applying auth.0009_alter_user_last_name_max_length... OK
Applying sessions.0001_initial... OK
migrate命令檢視INSTALLED_APPS設定,並根據mysite/settings.py檔案中的資料庫設定建立所有必要的資料庫表。(The migrate command looks at the INSTALLED_APPS setting and creates any necessary database tables according to the database settings in your mysite/settings.py file and the database migrations shipped with the app (we’ll cover those later). )
建立模型
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. 每個模型都有許多類變數,每個變量表示模型中的資料庫欄位。
每個欄位都由一個欄位類的例項Field表示——例如,用於字元欄位的CharField和DateTimeField。 這告訴Django每個欄位擁有什麼型別的資料。
每個Field例項(例如question_text或pub_date)的名稱是機器友好格式的欄位名稱。 您將在您的Python程式碼中使用此值,並且您的資料庫將使用它作為列名稱。
您可以使用可選的第一個位置引數指向一個欄位來指定一個人類可讀的名稱。在這個例子中,我們只為Question.pub_date定義了一個人類可讀的名字。
一些Field類具有必需的引數。 CharField, 例如,需要你給它一個 max_length. 這不僅在資料庫模式中使用,而且在驗證中使用,我們很快就會看到。
一個Field也可以有各種可選的引數;在這種情況下,我們已將votes的default值設定為0。
最後,請注意使用ForeignKey定義關係。 這告訴Django每個Choice都與單個Question有關(多對一)。 Django支援所有常見的資料庫關係:多對一,多對多和一對一。
啟用模型
首先我們需要告訴我們的專案安裝了polls應用程式。 要將該應用程式包含在我們的專案中,我們需要在INSTALLED_APPS設定中新增對其配置類的引用。 PollsConfig類位於polls/apps.py檔案中,因此它的虛線路徑為’polls.apps.PollsConfig’。 編輯mysite/settings.py檔案並將該點標識路徑新增到INSTALLED_APPS設定中。 它看起來像這樣:
INSTALLED_APPS = [
'polls.apps.PollsConfig',# our app
'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
您應該看到類似於以下內容的內容:
python3 manage.py makemigrations polls
Migrations for 'polls':
polls/migrations/0001_initial.py
- Create model Choice
- Create model Question
- Add field question to choice
再次執行migrate以在您的資料庫中建立這些模型表:
python3 manage.py migrate
Operations to perform:
Apply all migrations: admin, auth, contenttypes, polls, sessions
Running migrations:
Applying polls.0001_initial... OK
migrate命令採用所有尚未應用的遷移(Django使用名為django_migrations的資料庫中的特殊表來跟蹤哪些應用),並根據您的資料庫執行它們實質上,將您對模型所做的更改與資料庫中的模式同步。
遷移非常強大,隨著時間的推移,您可以隨時更改模型,而無需刪除資料庫或表並建立新的資料庫 - 它專門用於實時升級資料庫,而不會丟失資料。 我們將在本教程的後面部分更深入地介紹它們,但現在請記住進行模型更改的三步指南:
- 更改模型(在models.py中)。
- 執行python manage.py makemigrations為這些更改建立遷移
- 執行python manage.py migrate,將這些更改應用到資料庫。
使用單獨的命令來生成和應用遷移,因為您將遷移到您的版本控制系統並將它們與您的應用程式一起傳送;它們不僅使您的開發更容易,而且還可以被其他開發人員和生產使用。
玩轉API
現在,讓我們進入互動式Python shell並使用Django提供的API。 要呼叫Python shell,請使用以下命令:
$ python manage.py shell
我們使用這個命令而不是簡單地輸入"python"命令是因為 manage.py 將 DJANGO_SETTINGS_MODULE 設定為環境變數, 它將Python 檔案mysite/settings.py 的引入路徑告訴Django.
>>> from polls.models import Question, Choice # 將我們剛剛寫好的模型類引入.
# No questions are in the system yet.
>>> Question.objects.all()
<QuerySet []>
# 建立一個新的調查問題.
# 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.
>>> 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 (1)>]>
等一下。 <Question: Question object (1)> 不是這個物件的有效表現形式。 我們通過編輯Question模型(polls/models.py檔案中)並新增一個__str__()方法來修復Question和Choice:
from django.db import models
class Question(models.Model):
# ...
def __str__(self):
return self.question_text
class Choice(models.Model):
# ...
def __str__(self):
return self.choice_text
向模型中新增__ str __()方法很重要,不僅為了您在處理互動提示時的方便,還因為在Django自動生成的管理中使用了物件表示。
請注意,這些是普通的Python方法。 讓我們新增一個自定義方法,僅供演示:
def was_published_recently(self):
return self.pub_date >= timezone.now() - datetime.timedelta(days=1)
再次執行python manage.py shell,儲存這些更改並啟動一個新的Python互動式shell:
>>> from polls.models import Question, Choice
# 確認我們的 __str__() 方法已經正常工作.
>>> Question.objects.all()
<QuerySet [<Question: What's up?>]>
# Django 提供了豐富的資料庫查詢API通過
# 關鍵字引數來驅動
>>> Question.objects.filter(id=1)
<QuerySet [<Question: What's up?>]>
>>> Question.objects.filter(question_text__startswith='What')
<QuerySet [<Question: What's up?>]>
# 查詢今年釋出的所有問題
>>> from django.utils import timezone
>>> current_year = timezone.now().year
>>> Question.objects.get(pub_date__year=current_year)
<Question: What's up?>
# 查詢一個不存在的ID時會引發一個異常
>>> 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()
介紹Django Admin
1、建立超級管理員:
python3 manage.py createsuperuser
Username (leave blank to use 'fww'): admin
Email address: [email protected]
Password:
Password (again):
This password is too short. It must contain at least 8 characters.
This password is too common.
This password is entirely numeric.
Bypass password validation and create user anyway? [y/N]: N
Password:
Password (again):
This password is too common.
This password is entirely numeric.
Bypass password validation and create user anyway? [y/N]: y
Superuser created successfully.
2、啟動伺服器:
$ python manage.py runserver
在瀏覽器位址列輸入:http://127.0.0.1:8000/admin/, 你就可以看到管理員登入介面了。輸入使用者名稱和密碼,你應該看到Django管理索引頁面。您應該看到幾種可編輯的內容:組和使用者。 它們由Django提供的認證框架django.contrib.auth提供。
3、在admin中修改poll應用程式 但是我們的民意調查程式在哪裡? 它並沒有顯示在管理索引頁面上。
為此需要做的是: 我們需要網站控制檯 Question 物件有一個管理介面, 要做到這點,開啟polls/admin.py檔案,並編輯成:
from django.contrib import admin
# Register your models here.
from .models import Question
admin.site.register(Question)
現在我們已經註冊了Question,Django知道它應該顯示在管理索引頁面上.