(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 %}