编写你的第一个 Django 应用【半成品】
英语不好,幸好Django官方3.0版教程有中文版,对照官方教程将初学者部分过一下
win10 python 3.7.7
第1 部分
1 安装
python -m pip install Django
创建项目-打开命令行,cd
到一个你想放置你代码的目录(如:www),然后运行以下命令:
django-admin startproject mysite
2 测试
在www/mysite目录中打开命令行
python manage.py runserver 8000
3 创建投票应用
你的应用可以存放在任何 Python path 中定义的路径。在这个教程中,我们将在你的 manage.py
同级目录下创建投票应用。这样它就可以作为顶级模块导入,而不是 mysite
的子模块。
请确定你现在处于 manage.py
所在的目录下,然后运行这行命令来创建一个应用:
python manage.py startapp polls
这将会创建一个 polls
目录,这个目录结构包括了投票应用的全部内容。
4 编写第一个视图
打开 polls/views.py
,把下面这些 Python 代码输入进去:
from django.http import HttpResponse def index(request): return HttpResponse("Hello, world. You're at the polls index.")
这是 Django 中最简单的视图。如果想看见效果,我们需要将一个 URL 映射到它——这就是我们需要 URLconf 的原因了。
为了创建 URLconf,请在 polls 目录里新建一个 urls.py
文件,代码:
from django.urls import path from . import views urlpatterns = [ path('', views.index, name='index'), ]
下一步是要在根URLconf 文件中指定我们创建的 polls.urls
模块。在 mysite/urls.py
文件的 urlpatterns
列表里插入一个 include()
, 如下:
from django.contrib import admin from django.urls import include, path urlpatterns = [ path('polls/', include('polls.urls')), path('admin/', admin.site.urls), ]
函数 include()
允许引用其它 URLconfs。每当 Django 遇到 include()
时,它会截断与此项匹配的 URL 的部分,并将剩余的字符串发送到 URLconf 以供进一步处理。
可能要重新python manage.py runserver 8000
现在,用你的浏览器访问 http://localhost:8000/polls/,你应该能够看见 "Hello, world. You're at the polls index."
第 2 部分
1 数据库配置
现在,打开 mysite/settings.py
。这是个包含了 Django 项目设置的 Python 模块。可看到默认使用了SQLite
编辑 mysite/settings.py
文件,先设置 TIME_ZONE
为你自己时区,如:TIME_ZONE = 'Asia/Shanghai' USE_TZ = False
设置中文:LANGUAGE_CODE = 'zh-hans'
此外,关注一下文件头部的 INSTALLED_APPS
设置项。这里包括了会在你项目中启用的所有 Django 应用。
这些应用被默认启用是为了给常规项目提供方便。如:django.contrib.admin
-- 管理员站点
默认开启的某些应用需要至少一个数据表,所以,在使用他们之前需要在数据库中创建一些表。请执行以下命令:
python manage.py migrate
写给极简主义者:你可以在运行 migrate
前毫无顾虑地从 INSTALLED_APPS
里注释或者删除掉它们。 migrate
命令只会为在 INSTALLED_APPS
里声明了的应用进行数据库迁移。
2 创建模型
在这个投票应用中,需要创建两个模型:问题 Question
和选项 Choice。
Question
模型包括问题描述和发布时间。Choice
模型有两个字段,选项描述和当前得票数。每个选项属于一个问题。这些概念可以通过一个 Python 类来描述。按照下面的例子来编辑 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)
3 激活模型
但是首先得把 polls
应用安装到我们的项目里。(设计哲学:Django 应用是“可插拔”的。)
我们需要在配置类 INSTALLED_APPS
中添加设置。因为 PollsConfig
类写在文件 polls/apps.py
中,所以它的点式路径是 'polls.apps.PollsConfig'
。在文件 mysite/settings.py
中 INSTALLED_APPS
子项添加点式路径后,它看起来像这样:
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
通过运行 makemigrations
命令,Django 会检测你对模型文件的修改
现在,再次运行 migrate
命令,在数据库里创建新定义的模型的数据表:
python manage.py migrate
现在,你只需要记住,改变模型需要这三步:
- 编辑
models.py
文件,改变模型。 - 运行
python manage.py makemigrations
为模型的改变生成迁移文件。 - 运行
python manage.py migrate
来应用数据库迁移。
4 初试 API
编辑 Question
模型的代码(位于 polls/models.py
中),给 Question
和 Choice
增加 __str__()
方法。
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 自动生成的 admin 里也使用这个方法来表示对象。
让我们再为此模型添加一个自定义方法:
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
和 from django.utils import timezone
分别导入了 Python 的标准 datetime
模块和 Django 中和时区相关的 django.utils.timezone
工具模块。如果你不太熟悉 Python 中的时区处理,看看 时区支持文档 吧。
保存文件然后通过 python manage.py shell
命令再次打开 Python 交互式命令行:
from polls.models import Choice, Question,datetime
q = Question(question_text="What's new?", pub_date=datetime.datetime.now())
q.save()
q.id Question.objects.all()
阅读 访问关系对象 文档可以获取关于数据库关系的更多内容。想知道关于双下划线的更多用法,参见 查找字段 文档。数据库 API 的所有细节可以在 数据库 API 参考 文档中找到。
5 介绍 Django 管理页面
5.1 创建一个管理员账号
python manage.py createsuperuser
输入admin 及邮箱,设置密码如:1234
如果开发服务器未启动,用以下命令启动它:python manage.py runserver
现在,打开浏览器,转到你本地域名的 "/admin/" 目录, -- 比如 "http://127.0.0.1:8000/admin/" 。你应该会看见管理员登录界面:
5.2进入管理站点页面
现在,试着使用你在上一步中创建的超级用户来登录。然后你将会看到 Django 管理页面的索引页
(因为 翻译 功能默认是开着的,所以登录界面可能会使用你的语言,取决于你浏览器的设置和 Django 是否拥有你语言的翻译。)
你将会看到几种可编辑的内容:组和用户。它们是由 django.contrib.auth
提供的,这是 Django 开发的认证框架。
5.3 向管理页面中加入投票应用
但是我们的投票应用在哪呢?它没在索引页面里显示。
只需要再做一件事:我们得告诉管理员,问题 Question
对象需要一个后台接口。打开 polls/admin.py
文件,把它编辑成下面这样:
from django.contrib import admin from .models import Question admin.site.register(Question)
5.4体验便捷的管理功能
现在我们向管理页面注册了问题 Question
类。Django 知道它应该被显示在索引页里(刷新浏览器可以看到效果)
第 3 部分
编写更多视图
现在让我们向 polls/views.py
里添加更多视图。这些视图有一些不同,因为他们接收参数:
def detail(request, question_id): return HttpResponse("You're looking at question %s." % question_id) def results(request, question_id): response = "You're looking at the results of question %s." return HttpResponse(response % question_id) def vote(request, question_id): return HttpResponse("You're voting on question %s." % question_id)
把这些新视图添加进 polls.urls
模块里,只要添加几个 url()
函数调用就行:
polls/urls.py:
from django.urls import path from . import views urlpatterns = [ # ex: /polls/ path('', views.index, name='index'), # ex: /polls/5/ path('<int:question_id>/', views.detail, name='detail'), # ex: /polls/5/results/ path('<int:question_id>/results/', views.results, name='results'), # ex: /polls/5/vote/ path('<int:question_id>/vote/', views.vote, name='vote'), ]
然后看看你的浏览器,如果你转到 "/polls/34/" ,Django 将会运行 detail()
方法并且展示你在 URL 里提供的问题 ID。再试试 "/polls/34/vote/" 和 "/polls/34/vote/" ——你将会看到暂时用于占位的结果和投票页。
写一个真正有用的视图
每个视图必须要做的只有两件事:返回一个包含被请求页面内容的 HttpResponse
对象,或者抛出一个异常,比如 Http404
。至于你还想干些什么,随便你。Django 只要求返回的是一个 HttpResponse
,或者抛出一个异常。
让我们使用 Django 的模板系统,只要创建一个视图,就可以将页面的设计从代码中分离出来。
首先,在你的 polls
目录里创建一个 templates
目录。Django 将会在这个目录里查找模板文件。(默认的设置文件设置了 DjangoTemplates
后端,并将 APP_DIRS
设置成了 True。这一选项将会让 DjangoTemplates
在每个 INSTALLED_APPS
文件夹中寻找 "templates" 子目录。)
在你刚刚创建的 templates
目录里,再创建一个目录 polls
,然后在其中新建一个文件 index.html
。换句话说,你的模板文件的路径应该是 polls/templates/polls/index.html
。
将下面的代码输入到刚刚创建的模板文件index.html
中:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>My test page</title> </head> <body> {% if latest_question_list %} <ul> {% for question in latest_question_list %} <li><a href="/polls/{{ question.id }}/">{{ question.question_text }}</a></li> {% endfor %} </ul> {% else %} <p>No polls are available.</p> {% endif %} </body> </html>
然后,让我们更新一下 polls/views.py
里的 index
视图来使用模板:
from django.http import HttpResponse from django.template import loader from .models import Question def index(request): latest_question_list = Question.objects.order_by('-pub_date')[:5] template = loader.get_template('polls/index.html') context = { 'latest_question_list': latest_question_list, } return HttpResponse(template.render(context, request))
用你的浏览器访问 "/polls/" ,你将会看见一个无序列表
「载入模板,填充上下文,再返回由它生成的 HttpResponse
对象」是一个非常常用的操作流程。于是 Django 提供了一个快捷函数,我们用它来重写 index()
视图:polls/views.py:
from django.shortcuts import render from .models import Question def index(request): latest_question_list = Question.objects.order_by('-pub_date')[:5] context = {'latest_question_list': latest_question_list} return render(request, 'polls/index.html', context)
注意到,我们不再需要导入 loader
和 HttpResponse
。不过如果你还有其他函数(比如说 detail
, results
, 和 vote
)需要用到它的话,就需要保持 HttpResponse
的导入。
一个快捷函数: get_object_or_404()
¶
尝试用 get()
函数获取一个对象,如果不存在就抛出 Http404
错误也是一个普遍的流程。Django 也提供了一个快捷函数,下面是修改后的详情 detail()
视图代码polls/views.py:
from django.shortcuts import get_object_or_404, render from .models import Question # ... def detail(request, question_id): question = get_object_or_404(Question, pk=question_id) return render(request, 'polls/detail.html', {'question': question})
我们稍后再讨论你需要在 polls/detail.html
里输入什么,但是如果你想试试上面这段代码是否正常工作的话,你可以暂时把下面这段输进去:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>My test page</title>
</head>
<body>
{{ question }}
</body>
</html>
本教程就到这里吧,还是看官方原版吧。
参考:https://www.cnblogs.com/it-tsz/p/10099756.html
https://docs.djangoproject.com/zh-hans/3.0/
https://blog.csdn.net/MrNoboday/article/details/91805040