(1)查看python版本號:css
python -m django --version
(2) 建立Django項目html
django-admin startproject mysite
(3)測試開發服務器是否成功python
Desktop\bncDjango\mysite>python manage.py runserver
Django 自帶一個用純 Python 寫的輕量級的 Web 服務器。爲了讓你能快速的開發出想要的東西,由於你不須要進行配置生產級別的服務器(好比 Apache)方面的工做,除非你已經準備好投入生產環境了。千萬不要 將這個服務器用於和生產環境相關的任何地方。這個服務器只是爲了開發而設計的。(咱們在 Web 框架方面是專家,在 Web 服務器方面並非。)mysql
(4)建立應用模塊算法
python manage.py startapp polls
Application definition
INSTALLED_APPS = [
sql
'django.contrib.admin', # 管理員站點
'django.contrib.auth', # 認證受權系統
'django.contrib.contenttypes', # 內容類型框架
'django.contrib.sessions', # 會話框架
'django.contrib.messages', # 消息框架
'django.contrib.staticfiles', #管理靜態文件的框架
'polls', # 投票模塊]
(5)polls模型下編輯視圖view數據庫
django
from django.shortcuts import render
Create your views here.
from django.http import HttpResponse瀏覽器
def index(request):
服務器
return HttpResponse("Hello,this is my frist polls index.")
(6)polls模塊下映射url
from django.urls import path
from . import views
urlpatterns = [
path('', views.index,name='index'),]
(7)mysite主模塊下配置url
from django.contrib import admin
from django.urls import path,include # 注意導入include模塊
urlpatterns = [
path('polls/', include('polls.urls')), # 配置polls子模板url,支持正則
path('admin/', admin.site.urls),]
(8)網頁查詢http://localhost:8000/polls/
(9)數據庫配置與遷移
DATABASES = {
'default': {
# 'django.db.backends.sqlite3',
# 'django.db.backends.postgresql',
# 'django.db.backends.mysql',
# 'django.db.backends.oracle'
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
},
# MySQL數據庫配置
# 'mysql': {
# 'ENGINE': 'django.db.backends.mysql',
# 'NAME': 'all_news', # 數據庫名
# 'USER': 'root',
# 'PASSWORD': 'root',
# 'HOST': '127.0.0.1',
# 'PORT': '3306',
# }
}
python manage.py migrate
(10)編寫模型M
from django.db import models
Create your models here.
class Question(models.Model):
question_text = models.CharField(max_length=200)
pub_data = models.DateField('date published')
def __str__(self):
return self.question_text
class Choice(models.Model):
question = models.ForeignKey(Question,on_delete=models.CASCADE)
choice_text = models.CharField(max_length=200)
votes = models.IntegerField(default=0)
def __str__(self):
return self.choice_text
(11)激活模型
爲模型的改變生成遷移文件
python manage.py makemigrations polls
另外一種查看,選擇執行接收一個遷移的名稱,而後返回對應的 SQL
python manage.py sqlmigrate polls 0001
應用數據庫遷移
python manage.py migrate
(12)全自動後臺管理頁面
12.1 建立一個能登陸管理頁面的用戶,均爲admin
python manage.py createsuperuser
12.2 啓動開發服務器:
python manage.py runserver
http://127.0.0.1:8000/admin/login/?next=/admin/
12.3 進入站點
12.4 管理頁面中加入配置應用
from django.contrib import admin
Register your models here.
from .models import Question,Choice
admin.site.register(Question)
admin.site.register(Choice)
(13)編寫更多視圖
13.1 polls下的views
from django.shortcuts import render
from django.http import HttpResponse
問題索引頁
def index(request):
return HttpResponse("Hello,this is my frist polls index.")
問題詳情頁
def detail(request,question_id):
return HttpResponse("You're looking at question %s." % question_id)
問題結果頁
def results(request,question_id):
return HttpResponse("You're looking at the results of question %s." % question_id)
投票處理器
def vote(request,question_id):
return HttpResponse("You're voting on question %s." % question_id)
13.2 polls下的urls記得添加命名空間
from django.urls import path
from . import views
app_name = 'polls' #添加命名空間
urlpatterns = [
# ex: /polls/
path('', views.index,name='index'),
# ex: /polls/5/
path('
# ex: /polls/5/results/
path('
# ex: /polls/5/vote/
path('
13.3 查詢數據庫信息並頁面顯示
問題索引頁
def index(request):
latest_question_list = Question.objects.order_by('pub_data')[:3]
output = '
'.join([q.question_text for q in latest_question_list])
HttpResponse(template.render(context,request))
return HttpResponse(output)
(14)編寫模板T
14.1 在mysite下建立templates,並建立polls文件夾下建立index.html
<!DOCTYPE html>
{% if latest_question_list %}
{% for question in latest_question_list %}
- {{ question.question_text }}
{% endfor %}
{% else %}
No polls are available.
{% endif %}
能夠修改成(經常使用).想改爲 polls/specifics/12/
,你不用在模板裏修改任何東西(包括其它模板),只要在 polls/urls.py
裏稍微修改一下就行:
{% for question in latest_question_list %}
{{ question.question_text }}
{% endfor %}
14.2 在mysite的settings修改DIRS
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR,'template/')],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},]
14.3 polls/views.py 修改
from django.shortcuts import render
from django.http import HttpResponse
from django.template import loader
from polls.models import Question
問題索引頁
def index(request):
latest_question_list = Question.objects.order_by('pub_data')[:5]
# output = '
'.join([q.question_text for q in latest_question_list])
template = loader.get_template('polls/index.html')
context = {
'latest_question_list': latest_question_list,
}
return HttpResponse(template.render(context,request))
進一步能夠修改成(經常使用):
問題索引頁
def index(request):
latest_question_list = Question.objects.order_by('pub_data')[:5]
context = {'latest_question_list': latest_question_list}
return render(request,'polls/index.html',context)
14.4 在瀏覽器訪問 "/polls/" 查看:
(15)查看詳細頁面
15.1 polls下views.py
from django.http import Http404
問題詳情頁
def detail(request,question_id):
try:
question = Question.objects.get(pk=question_id)
except Question.DoesNotExist:
raise Http404("Question does not exist")
return render(request,'polls/detail.html', {'question':question,'question_id':question_id})
優化後的算法(經常使用)
from django.shortcuts import render,get_object_or_404
問題詳情頁
def detail(request,question_id):
question = get_object_or_404(Question, pk=question_id)
return render(request, 'polls/detail.html', {'question': question,'question_id':question_id})
15.2 template下detail.html
<!DOCTYPE html>
{{ question.question_text }}
{% for choice in question.choice_set.all %}
- {{ choice.choice_text }}
{% endfor %}
15.3 運行結果
(16)polls/detail.html詳細頁面添加一個表單form
{{ question.question_text }}
{% if error_message %}
{{ error_message }}
{% endif %}
每一個單選按鈕的 value
屬性是對應的各個 Choice 的 ID。每一個單選按鈕的 name
是 "choice"
。這意味着,當有人選擇一個單選按鈕並提交表單提交時,它將發送一個 POST 數據 choice=#
,其中# 爲選擇的 Choice 的 ID。這是 HTML 表單的基本概念。
action
爲 {% url 'polls:vote' question.id %}
,並設置 method="post"
。使用 method="post"是很是重要的,由於這個提交表單的行爲會改變服務器端的數據。當你須要建立一個改變服務器端數據的表單時,請使用`method="post"
。這不是 Django 的特定技巧;這是優秀的網站開發技巧。forloop.counter
指示 for
標籤已經循環多少次。因爲咱們建立一個 POST 表單(它具備修改數據的做用),因此咱們須要當心跨站點請求僞造。 謝天謝地,你沒必要太過擔憂,由於 Django 已經擁有一個用來防護它的很是容易使用的系統。 簡而言之,全部針對內部 URL 的 POST 表單都應該使用{% csrf_token %}
模板標籤。
(17) polls/views.py
視圖編輯
投票處理器
def vote(request,question_id):
question = get_object_or_404(Question, pk=question_id)
try:
selected_choice = question.choice_set.get(pk=request.POST['choice'])
except (KeyError, Choice.DoesNotExist):
return render(request, 'polls/detail.html', {
'question': question,
'error_message': "You didn't select a choice.",})
else:
selected_choice.votes +=1
selected_choice.save()
return HttpResponseRedirect(reverse('polls:results', args=(question.id,)))
request.POST
是一個類字典對象,讓你能夠經過關鍵字的名字獲取提交的數據。 這個例子中, request.POST['choice']
以字符串形式返回選擇的 Choice 的 ID。 request.POST
的值永遠是字符串。request.POST['choice']
數據中沒有提供 choice
, POST 將引起一個 KeyError
。上面的代碼檢查 KeyError
,若是沒有給出 choice
將從新顯示 Question 表單和一個錯誤信息。HttpResponseRedirect
而不是經常使用的 HttpResponse
、 HttpResponseRedirect
只接收一個參數:用戶將要被重定向的 URL。構造函數中使用 reverse()
函數。這個函數避免了咱們在視圖函數中硬編碼 URL。重定向的 URL 將調用 'results'
視圖來顯示最終的頁面。(18) 重定向results.html
from django.shortcuts import get_object_or_404, render
def results(request, question_id):
question = get_object_or_404(Question, pk=question_id)
return render(request, 'polls/results.html', {'question': question})
(19)通用視圖,代碼重構
19.1 detail()
視圖幾乎如出一轍。惟一的不一樣是模板的名字。
問題索引頁
def index(request):
latest_question_list = Question.objects.order_by('pub_data')[:5]
return render(request,'polls/index.html',{'latest_question_list': latest_question_list})
問題詳情頁
def detail(request,question_id):
question = get_object_or_404(Question, pk=question_id)
return render(request, 'polls/detail.html', {'question': question,'question_id':question_id})
問題結果頁
def results(request,question_id):
question = get_object_or_404(Question, pk=question_id)
return render(request, 'polls/results.html', {'question': question})
19.2 建立一個 polls/results.html
模板
{{ question.question_text }}
{% for choice in question.choice_set.all %}
- {{ choice.choice_text }} -- {{ choice.votes }} vote{{ choice.votes|pluralize }}
{% endfor %}
19.3 通用視圖系統
通用視圖將常見的模式抽象化,可使你在編寫應用時甚至不須要編寫Python代碼。將咱們的投票應用轉換成使用通用視圖系統,這樣咱們能夠刪除許多咱們的代碼。咱們僅僅須要作如下幾步來完成轉換,
1 改良URLconf
打開 polls/urls.py
這個 URLconf 並將它修改爲:路徑字符串中匹配模式的名稱已經由 <question_id>
改成 <pk>
。
from django.urls import path
from . import views
app_name = 'polls'
urlpatterns = [
path('', views.IndexView.as_view(), name='index'),
path('
path('
path('
2 改良視圖
刪除舊的 index
, detail
, 和 results
視圖,並用 Django 的通用視圖代替。打開 polls/views.py
文件,並將它修改爲:
from django.http import HttpResponseRedirect
from django.shortcuts import get_object_or_404, render
from django.urls import reverse
from django.views import generic
from .models import Choice, Question
class IndexView(generic.ListView):
template_name = 'polls/index.html'
context_object_name = 'latest_question_list'
def get_queryset(self):
return Question.objects.order_by('pub_date')[:5]
class DetailView(generic.DetailView):
model = Question
template_name = 'polls/detail.html'
class ResultsView(generic.DetailView):
model = Question
template_name = 'polls/results.html'
def vote(request,question_id):
question = get_object_or_404(Question, pk=question_id)
try:
selected_choice = question.choice_set.get(pk=request.POST['choice'])
except (KeyError, Choice.DoesNotExist):
return render(request, 'polls/detail.html', {
'question': question,
'error_message': "You didn't select a choice.",
})
else:
selected_choice.votes +=1
selected_choice.save()
return HttpResponseRedirect(reverse('polls:results', args=(question.id,)))
model
屬性提供。DetailView
指望從 URL 中捕獲名爲 "pk"
的主鍵值,因此咱們爲通用視圖把 question_id
改爲 pk
。19.4 運行程序
主頁面
子頁面
詳情頁面
(20)自動化測試
20.1 測試的策略
20.2 第一個測試
需求:咱們的要求是若是 Question 是在一天以內發佈,was_published_recently()方法將會返回
True,然而如今這個方法在
Question的
pub_date` 字段比當前時間還晚時也會返回 True
編寫測試代碼:
from django.test import TestCase
Create your tests here.
from django.utils import timezone
from .models import Question
class QuestionModelTests(TestCase):
def test_was_published_recently_with_future_question(self):
"""
was_published_recently() returns False for questions whose pub_date
is in the future.
"""
time = timezone.now() + datetime.timedelta(days=30)
future_question = Question(pub_date=time)
self.assertIs(future_question.was_published_recently(), False)
運行代碼:$ python manage.py test polls
測試結果:
python manage.py test polls
將會尋找 polls
應用裏的測試代碼django.test.TestCase
的一個子類test
開頭的方法。test_was_published_recently_with_future_question
方法中,它建立了一個 pub_date
值爲 30 天后的 Question
實例。assertls()
方法,發現 was_published_recently()
返回了 True
,而咱們指望它返回 False
。測試系統通知咱們哪些測試樣例失敗了,和形成測試失敗的代碼所在的行號。
(21)靜態文件(圖片/腳本/樣式)
對於小項目來講,靜態文件隨便放在哪,只要服務程序可以找到它們就行。然而在大項目中,處理不一樣應用所須要的靜態文件的工做就顯得有點麻煩了。這就是 django.contrib.staticfiles
存在的意義
建立的 static
文件夾中建立 polls
的文件夾,再在 polls
文件夾中建立一個名爲 style.css
的文件。樣式表路徑應是 polls/static/polls/style.css
。由於 AppDirectoriesFinder
的存在,你能夠在 Django 中簡單地使用以 polls/style.css
的形式引用此文件,相似你引用模板路徑的方式。
li a { color: green; }
polls的index.html引用
{% load static %}
添加圖片
咱們會建立一個用於存在圖像的目錄。在 polls/static/polls
目錄下建立一個名爲 images
的子目錄。在這個目錄中,放一張名爲 background.gif
的圖片。換言之,在目錄 polls/static/polls/images/background.jpg
中放一張圖片。
body {
background: white url("images/background.gif") no-repeat;
}
更多關於設置和框架的資料,參考 靜態文件解惑 和 靜態文件指南。部署靜態文件 介紹瞭如何在真實服務器上使用靜態文件。
(22) 編寫第一個django應用
22.1 polls/admin定義後臺表單,列表爲字段顯示順序
from django.contrib import admin
Register your models here.
from .models import Question,Choice
class QuestionAdmin(admin.ModelAdmin):
# fieldsets = [
# ('問題內容', {'fields': ['question_text']}),
# ('發佈時間', {'fields': ['pub_data']}),
# ]
# fields = ['pub_data', 'question_text']
list_display = ('question_text', 'pub_data')
admin.site.register(Question, QuestionAdmin)
class ChoiceAdmin(admin.ModelAdmin):
# fields = ['question','choice_text', 'votes']
list_display = ('question','choice_text', 'votes')
admin.site.register(Choice, ChoiceAdmin)
22.2 字段過濾器
class QuestionAdmin(admin.ModelAdmin):
list_display = ('question_text', 'pub_data')
list_filter = ['pub_data'] # 過濾器
admin.site.register(Question, QuestionAdmin)
22.3 自定義後臺界面與風格
mysite/settings.py
,牢記),在 TEMPLATES
設置中添加 DIRS
選項:在 templates
目錄內建立名爲 admin
的目錄,隨後,將存放 Django 默認模板的目錄(django/contrib/admin/templates
)內的模板文件 admin/base_site.html
複製到這個目錄內。Django 的源文件在哪裏?$ python -c "import django; print(django.__path__)"
接着,用你站點的名字替換文件內的 [](https://docs.djangoproject.com/zh-hans/2.2/intro/tutorial07/#id1){{ site_header|default:_('Django administration') }}
(包含大括號)。完成後,你應該看到以下代碼:
{% block branding %}
Polls Administration
{% endblock %}