數據庫配置
mysite/settings.py
這是個包含了 Django 項目設置的 Python 模塊。
這個配置文件使用 SQLite 作爲默認數據庫,python內置SQLite。
如何使用其他的數據庫?
- 安裝合適的 database bindings
- 改變設置文件中 DATABASES 'default' 項目中的一些鍵值
ENGINE可選值:
'django.db.backends.sqlite3'
'django.db.backends.postgresql'
'django.db.backends.mysql'
-
'django.db.backends.oracle'
- 其它後端
NAME數據庫名稱
如果使用的是 SQLite,數據庫將是你電腦上的一個文件,在這種情況下, NAME
應該是此文件的絕對路徑,包括文件名。默認值 os.path.join(BASE_DIR, 'db.sqlite3')
將會把數據庫文件儲存在項目的根目錄。
如果你不使用 SQLite,則必須添加一些額外設置,比如 USER
、 PASSWORD
、 HOST
等等。
創建數據表
INSTALLED_APPS
設置項。這裏包括了會在你項目中啓用的所有 Django 應用。
django.contrib.admin
-- 管理員站點, 你很快就會使用它。django.contrib.auth
-- 認證授權系統。django.contrib.contenttypes
-- 內容類型框架。django.contrib.sessions
-- 會話框架。django.contrib.messages
-- 消息框架。django.contrib.staticfiles
-- 管理靜態文件的框架。
默認開啓的某些應用需要至少一個數據表,所以,在使用他們之前需要在數據庫中創建一些表。
#migrate 命令檢查 INSTALLED_APPS 設置,爲其中的每個應用創建需要的數據表
python manage.py migrate
怎樣關閉默認開啓的應用?
如果你不需要某個或某些應用,你可以在運行 migrate
前從 INSTALLED_APPS
裏註釋或者刪除掉它們。 migrate
命令只會爲在 INSTALLED_APPS
裏聲明瞭的應用進行數據庫遷移。
創建模型
在 Django 裏寫一個數據庫驅動的 Web 應用的第一步是定義模型,數據庫結構設計和附加的其它元數據。
在這個簡單的投票應用中,需要創建兩個模型:
問題 Question
和選項 Choice
。
Question
模型包括問題描述和發佈時間。Choice
模型有兩個字段,選項描述和當前得票數。
每個選項屬於一個問題。
polls/models.py
#導入models模塊
from django.db import models
#Question模型
class Question(models.Model):
question_text = models.CharField(max_length=200) #問題描述字段,字段長度200
pub_date = models.DateTimeField('date published') #發佈日期字段,Date格式
#Choice模型
class Choice(models.Model):
question = models.ForeignKey(Question, on_delete=models.CASCADE) #與Question設置聯繫,id主鍵。使用 ForeignKey 定義了一個關係。這將告訴 Django,每個 Choice 對象都關聯到一個 Question 對象。
choice_text = models.CharField(max_length=200) #選項名稱字段,字段長度200
votes = models.IntegerField(default=0) #投票數,默認值爲0
激活模型
通過models.py的代碼,django可以
- 爲這個應用創建數據庫 schema(生成
CREATE TABLE
語句)。 - 創建可以與
Question
和Choice
對象進行交互的 Python 數據庫 API。
把 polls
應用安裝到項目
Django 應用是“可插拔”的。你可以在多個項目中使用同一個應用。
在配置類 INSTALLED_APPS
中添加設置
INSTALLED_APPS = [
'polls.apps.PollsConfig', # PollsConfig 類寫在文件 polls/apps.py 中,所以它的點式路徑是 'polls.apps.PollsConfig'。
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
]
#通過運行 makemigrations 命令,Django 會檢測你對模型文件的修改(在這種情況下,你已經取得了新的),並且把修改的部分儲存爲一次 遷移。
python manage.py makemigrations polls
#遷移命令會執行哪些 SQL 語句
python manage.py sqlmigrate polls 0001
#在數據庫裏創建新定義的模型的數據表
python manage.py migrate
遷移是非常強大的功能,它能讓你在開發過程中持續的改變數據庫結構而不需要重新刪除和創建表 - 它專注於使數據庫平滑升級而不會丟失數據。
改變模型三步走:
- 編輯
models.py
文件,改變模型。、 - 運行
python manage.py makemigrations
爲模型的改變生成遷移文件。 - 運行
python manage.py migrate
來應用數據庫遷移。
API
#打開python命令行
python manage.py shell
#導入Quesiton和Choice模型
>>>from polls.models import Choice, Question
#查看Question模型的所有實例
>>>Question.objects.all()
<QuerySet []> #目前爲空
#導入時區timezone模塊
>>>from django.utils import timezone
#創建一個Question對象
>>> q = Question(question_text="What's new?", pub_date=timezone.now())
#保存Question對象到數據庫
>>>q.save()
#顯示Question對象q的ID
>>>q.id
1
#顯示Question對象q的屬性
>>>q.question_text
"What's new?"
>>>q.pub_date
datetime.datetime(2012, 2, 26, 13, 0, 0, 775217, tzinfo=<UTC>)
#改變q的question_text的值
>>>q.quextion_text="What's up?"
>>>q.save()
#顯示數據庫中所有的Question對象
>>>Question.objects.all()
<QuerySet [<Question: Question object (1)>]>
__str__()
<Question: Question object (1)>
對於我們瞭解這個對象的細節沒什麼幫助。
給 Question
和 Choice
增加 __str__()
方法,
polls/models.py
from django.db import models
class Question(models.Model):
# ...
def __str__(self):
return self.question_text #Question.objects.all()顯示qwuestion_text
class Choice(models.Model):
# ...
def __str__(self):
return self.choice_text
在模型裏添加自定義方法
polls/models.py
import datetime
from django.db import models
from django.utils import timezone
class Question(models.Model):
# ...
#自定義方法,最近發佈的Question
def was_published_recently(self):
return self.pub_date >= timezone.now() - datetime.timedelta(days=1)
打開shell,
>>>from polls.models import Choice, Question
#驗證__str()__是否起作用
>>> Question.objects.all()
<QuerySet [<Question: What's up?>]>
#Django提供數據庫lookup API
>>> Question.objects.filter(id=1)
<QuerySet [<Question: What's up?>]>
>>> Question.objects.filter(question_text__startswith='What')
<QuerySet [<Question: What's up?>]>
#篩選pub_date
>>> from django.utils import timezone
>>> current_year = timezone.now().year
>>> Question.objects.get(pub_date__year=current_year)
<Question: What's up?>
#通過主鍵pk進行lookup
>>> Question.objects.get(pk=1)
<Question: What's up?>
#確保自定義的方法生效
>>> q = Question.objects.get(pk=1)
>>> q.was_published_recently()
True
#顯示q所有的choice
>>> q.choice_set.all()
<QuerySet []>
#通過get顯示指定Question的choice_set
>>> Question.objects.get(pk=1).choice_set.all()
<QuerySet [<Choice: Not much >, <Choice: sky >, <Choice: Just hacking again>]>
>>> Question.objects.get(pk=2).choice_set.all()
<QuerySet []>
#通過filter顯示指定Question的choice_set
#filter返回的是一個集合,需要指定其中的一個成員後使用choice_set.all()
>>> Question.objects.filter(id=1)[0].choice_set.all()
<QuerySet [<Choice: Not much >, <Choice: sky >, <Choice: Just hacking again>]>
>>> Question.objects.filter(id=2)[0].choice_set.all()
<QuerySet []>
#創建選項
>>> 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的對象c的API能夠訪問與之關聯的Question對象
>>>c.question
<Question: What's up?>
#顯示指定question對象的choice集合
>>> q.choice_set.all()
<QuerySet [<Choice: Not much>, <Choice: The sky>, <Choice: Just hacking again>]>
#顯示指定question對象的choice的數目
>>> q.choice_set.count()
3
>>> Choice.objects.filter(question__pub_date__year=current_year)
<QuerySet [<Choice: Not much>, <Choice: The sky>, <Choice: Just hacking again>]>
#刪除指定的choice
>>> c = q.choice_set.filter(choice_text__startswith='Just hacking')
>>> c.delete()