安装
pip3 install Django
创建项目
django-admin.py startproject {项目名称}
如果提示`You have 17 unapplied migration(s). Your project may not work properly until you apply the migrations for app(s): admin, auth, contenttypes, sessions.
Run 'python manage.py migrate' to apply them.` 请换个项目名, 不能和py模块相同如果提示Django需要权限使用
python manage.py migrate
启动项目
python manage.py runserver
or
python3 manage.py runserver 0.0.0.0:8000
》如果使用sh运行项目失败, 把项目目录权限开放
Permission denied
···
sudo chmod -R 777 {项目目录}
···
默认安装最新release版
pip3 install Django
安装开发版
git clone https://github.com/django/django.git
pip3 install -e django/
验证
在py下
import django
print(django.get_version())
//3.0.6
或终端下
python3 -m django --version
创建项目
django-admin startproject mysite
避免使用 Python 或 Django 的内部保留字来命名你的项目
项目结构
mysite/
manage.py
mysite/
__init__.py
settings.py
urls.py
asgi.py
wsgi.py
- 根目录可随意更改, 不影响项目
-
manage.py
: 一个让你用各种方式管理 Django 项目的命令行工具。你可以阅读 django-admin and manage.py 获取所有manage.py
的细节。 - 里面一层的
mysite
/ 目录包含你的项目,它是一个纯 Python 包。它的名字就是当你引用它内部任何东西时需要用到的 Python 包名。 (比如mysite
.urls). -
mysite/__init__.py
:一个空文件,告诉 Python 这个目录应该被认为是一个 Python 包。如果你是 Python 初学者,阅读官方文档中的 更多关于包的知识")。 -
mysite/settings.py
:Django 项目的配置文件。如果你想知道这个文件是如何工作的,请查看 Django settings 了解细节。 -
mysite/urls.py
:Django 项目的 URL 声明,就像你网站的“目录”。阅读 URL dispatcher 文档来获取更多关于 URL 的内容。 -
mysite/asgi.py
:作为你的项目的运行在 ASGI 兼容的Web服务器上的入口。阅读 如何使用 WSGI 进行部署
了解更多细节。 -
mysite/wsgi.py
:作为你的项目的运行在 WSGI 兼容的Web服务器上的入口。阅读 如何使用如何使用 WSGI 进行部署 了解更多细节。
创建应用 投票
···
python3 manage.py startapp polls
···
···
polls/
__init__.py
admin.py
apps.py
migrations/
__init__.py
models.py
tests.py
views.py
···
编写第一个视图
polls/views.py
···
from django.http import HttpResponse
def index(request):
return HttpResponse("Hello, world. You're at the polls index.")
···
polls/urls.py
from django.urls import path
from . import views
urlpatterns = [
path('', views.index, name='index'),
]
mysite/urls.py
from django.contrib import admin
from django.urls import include, path
urlpatterns = [
path('polls/', include('polls.urls')),
path('admin/', admin.site.urls),
]
运行服务器
···
python3 manage.py runserver
···
》默认0.0.0.0:8000 相同
如果运行时提示·You have 17 unapplied migration(s). Your project may not work properly until you apply the migrations for app(s): admin, auth, contenttypes, sessions. Run 'python manage.py migrate' to apply them.· 使用·python3 manage.py migrate· 获取权限
···
python3 manage.py runserver 8080
python3 manage.py runserver 0:8000
···
自动重新加载的服务器
用于开发的服务器在需要的情况下会对每一次的访问请求重新载入一遍 Python 代码。所以你不需要为了让修改的代码生效而频繁的重新启动服务器。然而,一些动作,比如添加新文件,将不会触发自动重新加载,这时你得自己手动重启服务器。
访问网址
···
http://127.0.0.1:8000/polls/
···
api
path
函数 path()
具有四个参数,两个必须参数:route
和 view
,两个可选参数:kwargs
和 name
。现在,是时候来研究这些参数的含义了。
- route 是一个匹配 URL 的准则(类似正则表达式)。当 Django 响应一个请求时,它会从 urlpatterns 的第一项开始,按顺序依次匹配列表中的项,直到找到匹配的项。 这些准则不会匹配 GET 和 POST 参数或域名。例如,URLconf 在处理请求 https://www.example.com/myapp/ 时,它会尝试匹配 myapp/ 。处理请求 https://www.example.com/myapp... 时,也只会尝试匹配 myapp/。
- view 当 Django 找到了一个匹配的准则,就会调用这个特定的视图函数,并传入一个 HttpRequest 对象作为第一个参数,被“捕获”的参数以关键字参数的形式传入。稍后,我们会给出一个例子。
- kwargs 任意个关键字参数可以作为一个字典传递给目标视图函数。本教程中不会使用这一特性。
- name 为你的 URL 取名能使你在 Django 的任意地方唯一地引用它,尤其是在模板中。这个有用的特性允许你只改一个文件就能全局地修改某个 URL 模式。
现在,打开 mysite/settings.py
。这是个包含了 Django 项目设置的 Python 模块。
通常,这个配置文件使用 SQLite 作为默认数据库。如果你不熟悉数据库,或者只是想尝试下 Django,这是最简单的选择。Python 内置 SQLite,所以你无需安装额外东西来使用它。当你开始一个真正的项目时,你可能更倾向使用一个更具扩展性的数据库,例如 PostgreSQL,避免中途切换数据库这个令人头疼的问题。
如果你想使用其他数据库,你需要安装合适的 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 等等。想了解更多数据库设置方面的内容,请看文档:DATABASES
SQLite 以外的其它数据库
如果你使用了 SQLite 以外的数据库,请确认在使用前已经创建了数据库。你可以通过在你的数据库交互式命令行中使用 "CREATE DATABASE database_name;" 命令来完成这件事。
另外,还要确保该数据库用户中提供 mysite/settings.py 具有 "create database" 权限。这使得自动创建的 test database 能被以后的教程使用。
如果你使用 SQLite,那么你不需要在使用前做任何事——数据库会在需要的时候自动创建。
编辑 mysite/settings.py 文件前,先设置 TIME_ZONE
为你自己时区(Asia/Shanghai
)。
此外,关注一下文件头部的 INSTALLED_APPS 设置项。这里包括了会在你项目中启用的所有 Django 应用。应用能在多个项目中使用,你也可以打包并且发布应用,让别人使用它们。
通常, INSTALLED_APPS 默认包括了以下 Django 的自带应用:
`django.contrib.admin` -- 管理员站点, 你很快就会使用它。
`django.contrib.auth` -- 认证授权系统。
`django.contrib.contenttypes` -- 内容类型框架。
`django.contrib.sessions` -- 会话框架。
`django.contrib.messages` -- 消息框架。
`django.contrib.staticfiles` -- 管理静态文件的框架。
为这些应用创建数据表
默认开启的某些应用需要至少一个数据表,所以,在使用他们之前需要在数据库中创建一些表。请执行以下命令:
python manage.py migrate
这个 migrate 命令检查 INSTALLED_APPS 设置,为其中的每个应用创建需要的数据表,至于具体会创建什么,这取决于你的 mysite/settings.py 设置文件和每个应用的数据库迁移文件(我们稍后会介绍这个)。这个命令所执行的每个迁移操作都会在终端中显示出来。如果你感兴趣的话,运行你数据库的命令行工具,并输入\dt (PostgreSQL), SHOW TABLES; (MariaDB,MySQL), .schema (SQLite)
或者SELECT TABLE_NAME FROM USER_TABLES; (Oracle)
来看看 Django 到底创建了哪些表。就像之前说的,为了方便大多数项目,我们默认激活了一些应用,但并不是每个人都需要它们。如果你不需要某个或某些应用,你可以在运行 migrate 前毫无顾虑地从 INSTALLED_APPS 里注释或者删除掉它们。 migrate 命令只会为在 INSTALLED_APPS 里声明了的应用进行数据库迁移。
创建模型
在 Django 里写一个数据库驱动的 Web 应用的第一步是定义模型 - 也就是数据库结构设计和附加的其它元数据。
模型是真实数据的简单明确的描述。它包含了储存的数据所必要的字段和行为。Django 遵循 DRY Principle 。它的目标是你只需要定义数据模型,然后其它的杂七杂八代码你都不用关心,它们会自动从模型生成。
来介绍一下迁移 - 举个例子,不像 Ruby On Rails,Django 的迁移代码是由你的模型文件自动生成的,它本质上是个历史记录,Django 可以用它来进行数据库的滚动更新,通过这种方式使其能够和当前的模型匹配。
在这个投票应用中,需要创建两个模型:问题 Question
和选项 Choice
。Question
模型包括问题描述和发布时间。Choice
模型有两个字段,选项描述和当前得票数。每个选项属于一个问题。
这些概念可以通过一个 Python 类来描述。按照下面的例子来编辑 polls/models.py
文件:
例子
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)
创建了两个table, 两个之间还有关联
激活模型
上面的一小段用于创建模型的代码给了 Django 很多信息,通过这些信息,Django 可以:
- 为这个应用创建数据库 schema(生成 CREATE TABLE 语句)。
- 创建可以与 Question 和 Choice 对象进行交互的 Python 数据库 API。
但是首先得把 polls 应用安装到我们的项目里。
为了在我们的工程中包含这个应用,我们需要在配置类 INSTALLED_APPS 中添加设置。因为 PollsConfig 类写在文件 polls/apps.py 中,所以它的点式路径是 'polls.apps.PollsConfig'。在文件 mysite/settings.py 中 INSTALLED_APPS 子项添加点式路径后,它看起来像这样:
mysite/settings.py
INSTALLED_APPS = [
'polls.apps.PollsConfig', //添加
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
]
配置应用
python3 manage.py makemigrations polls
Migrations for 'polls':
polls/migrations/0001_initial.py
- Create model Question
- Create model Choice
Getting Help
语言: zh-hans
文档版本: 3.0
编写你的第一个 Django 应用,第 2 部分¶
这部分教程从 教程第 1 部分 结尾的地方继续讲起。我们将建立数据库,创建您的第一个模型,并主要关注 Django 提供的自动生成的管理页面。
从哪里获得帮助:
如果你在阅读本教程的过程中有任何疑问,可以前往FAQ的:doc:Getting Help 的版块。
数据库配置¶
现在,打开 mysite/settings.py 。这是个包含了 Django 项目设置的 Python 模块。
通常,这个配置文件使用 SQLite 作为默认数据库。如果你不熟悉数据库,或者只是想尝试下 Django,这是最简单的选择。Python 内置 SQLite,所以你无需安装额外东西来使用它。当你开始一个真正的项目时,你可能更倾向使用一个更具扩展性的数据库,例如 PostgreSQL,避免中途切换数据库这个令人头疼的问题。
如果你想使用其他数据库,你需要安装合适的 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 等等。想了解更多数据库设置方面的内容,请看文档:DATABASES 。
SQLite 以外的其它数据库
如果你使用了 SQLite 以外的数据库,请确认在使用前已经创建了数据库。你可以通过在你的数据库交互式命令行中使用 "CREATE DATABASE database_name;" 命令来完成这件事。
另外,还要确保该数据库用户中提供 mysite/settings.py 具有 "create database" 权限。这使得自动创建的 test database 能被以后的教程使用。
如果你使用 SQLite,那么你不需要在使用前做任何事——数据库会在需要的时候自动创建。
编辑 mysite/settings.py 文件前,先设置 TIME_ZONE 为你自己时区。
此外,关注一下文件头部的 INSTALLED_APPS 设置项。这里包括了会在你项目中启用的所有 Django 应用。应用能在多个项目中使用,你也可以打包并且发布应用,让别人使用它们。
通常, INSTALLED_APPS 默认包括了以下 Django 的自带应用:
django.contrib.admin -- 管理员站点, 你很快就会使用它。
django.contrib.auth -- 认证授权系统。
django.contrib.contenttypes -- 内容类型框架。
django.contrib.sessions -- 会话框架。
django.contrib.messages -- 消息框架。
django.contrib.staticfiles -- 管理静态文件的框架。
这些应用被默认启用是为了给常规项目提供方便。
默认开启的某些应用需要至少一个数据表,所以,在使用他们之前需要在数据库中创建一些表。请执行以下命令:
/
$ python manage.py migrate
这个 migrate 命令检查 INSTALLED_APPS 设置,为其中的每个应用创建需要的数据表,至于具体会创建什么,这取决于你的 mysite/settings.py 设置文件和每个应用的数据库迁移文件(我们稍后会介绍这个)。这个命令所执行的每个迁移操作都会在终端中显示出来。如果你感兴趣的话,运行你数据库的命令行工具,并输入 dt (PostgreSQL), SHOW TABLES; (MariaDB,MySQL), .schema (SQLite)或者 SELECT TABLE_NAME FROM USER_TABLES; (Oracle) 来看看 Django 到底创建了哪些表。
写给极简主义者
就像之前说的,为了方便大多数项目,我们默认激活了一些应用,但并不是每个人都需要它们。如果你不需要某个或某些应用,你可以在运行 migrate 前毫无顾虑地从 INSTALLED_APPS 里注释或者删除掉它们。 migrate 命令只会为在 INSTALLED_APPS 里声明了的应用进行数据库迁移。
创建模型¶
在 Django 里写一个数据库驱动的 Web 应用的第一步是定义模型 - 也就是数据库结构设计和附加的其它元数据。
设计哲学
模型是真实数据的简单明确的描述。它包含了储存的数据所必要的字段和行为。Django 遵循 DRY Principle 。它的目标是你只需要定义数据模型,然后其它的杂七杂八代码你都不用关心,它们会自动从模型生成。
来介绍一下迁移 - 举个例子,不像 Ruby On Rails,Django 的迁移代码是由你的模型文件自动生成的,它本质上是个历史记录,Django 可以用它来进行数据库的滚动更新,通过这种方式使其能够和当前的模型匹配。
在这个投票应用中,需要创建两个模型:问题 Question 和选项 Choice。Question 模型包括问题描述和发布时间。Choice 模型有两个字段,选项描述和当前得票数。每个选项属于一个问题。
这些概念可以通过一个 Python 类来描述。按照下面的例子来编辑 polls/models.py 文件:
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)
每个模型被表示为 django.db.models.Model 类的子类。每个模型有许多类变量,它们都表示模型里的一个数据库字段。
每个字段都是 Field 类的实例 - 比如,字符字段被表示为 CharField ,日期时间字段被表示为 DateTimeField 。这将告诉 Django 每个字段要处理的数据类型。
每个 Field 类实例变量的名字(例如 question_text 或 pub_date )也是字段名,所以最好使用对机器友好的格式。你将会在 Python 代码里使用它们,而数据库会将它们作为列名。
你可以使用可选的选项来为 Field 定义一个人类可读的名字。这个功能在很多 Django 内部组成部分中都被使用了,而且作为文档的一部分。如果某个字段没有提供此名称,Django 将会使用对机器友好的名称,也就是变量名。在上面的例子中,我们只为 Question.pub_date 定义了对人类友好的名字。对于模型内的其它字段,它们的机器友好名也会被作为人类友好名使用。
定义某些 Field 类实例需要参数。例如 CharField 需要一个 max_length 参数。这个参数的用处不止于用来定义数据库结构,也用于验证数据,我们稍后将会看到这方面的内容。
Field 也能够接收多个可选参数;在上面的例子中:我们将 votes 的 default 也就是默认值,设为0。
注意在最后,我们使用 ForeignKey 定义了一个关系。这将告诉 Django,每个 Choice 对象都关联到一个 Question 对象。Django 支持所有常用的数据库关系:多对一、多对多和一对一。
激活模型¶
上面的一小段用于创建模型的代码给了 Django 很多信息,通过这些信息,Django 可以:
为这个应用创建数据库 schema(生成 CREATE TABLE 语句)。
创建可以与 Question 和 Choice 对象进行交互的 Python 数据库 API。
但是首先得把 polls 应用安装到我们的项目里。
设计哲学
Django 应用是“可插拔”的。你可以在多个项目中使用同一个应用。除此之外,你还可以发布自己的应用,因为它们并不会被绑定到当前安装的 Django 上。
为了在我们的工程中包含这个应用,我们需要在配置类 INSTALLED_APPS 中添加设置。因为 PollsConfig 类写在文件 polls/apps.py 中,所以它的点式路径是 'polls.apps.PollsConfig'。在文件 mysite/settings.py 中 INSTALLED_APPS 子项添加点式路径后,它看起来像这样:
mysite/settings.py
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
你将会看到类似于下面这样的输出:
Migrations for 'polls':
polls/migrations/0001_initial.py
- Create model Question
- Create model Choice
通过运行 makemigrations 命令,Django 会检测你对模型文件的修改(在这种情况下,你已经取得了新的),并且把修改的部分储存为一次 迁移。
迁移是 Django 对于模型定义(也就是你的数据库结构)的变化的储存形式 - 它们其实也只是一些你磁盘上的文件。如果你想的话,你可以阅读一下你模型的迁移数据,它被储存在 polls/migrations/0001_initial.py 里。别担心,你不需要每次都阅读迁移文件,但是它们被设计成人类可读的形式,这是为了便于你手动调整Django的修改方式。
Django 有一个自动执行数据库迁移并同步管理你的数据库结构的命令 - 这个命令是 migrate,我们马上就会接触它 - 但是首先,让我们看看迁移命令会执行哪些 SQL 语句。sqlmigrate 命令接收一个迁移的名称,然后返回对应的 SQL:
检查 sql
python3 manage.py sqlmigrate polls 0001
请注意以下几点:
- 输出的内容和你使用的数据库有关,上面的输出示例使用的是 PostgreSQL。
- 数据库的表名是由应用名(polls)和模型名的小写形式( question 和 choice)连接而来。(如果需要,你可以自定义此行为。)
- 主键(IDs)会被自动创建。(当然,你也可以自定义。)
默认的,Django 会在外键字段名后追加字符串 "_id" 。(同样,这也可以自定义。)
外键关系由 FOREIGN KEY 生成。你不用关心 DEFERRABLE 部分,它只是告诉 PostgreSQL,请在事务全都执行完之后再创建外键关系。
生成的 SQL 语句是为你所用的数据库定制的,所以那些和数据库有关的字段类型,比如 auto_increment (MySQL)、 serial (PostgreSQL)和 integer primary key autoincrement (SQLite),Django 会帮你自动处理。那些和引号相关的事情 - 例如,是使用单引号还是双引号 - 也一样会被自动处理。
这个 sqlmigrate 命令并没有真正在你的数据库中的执行迁移 - 相反,它只是把命令输出到屏幕上,让你看看 Django 认为需要执行哪些 SQL 语句。这在你想看看 Django 到底准备做什么,或者当你是数据库管理员,需要写脚本来批量处理数据库时会很有用。
如果你感兴趣,你也可以试试运行 python manage.py check ;这个命令帮助你检查项目中的问题,并且在检查过程中不会对数据库进行任何操作。
python manage.py check
创建数据表
现在,再次运行 migrate 命令,在数据库里创建新定义的模型的数据表:
python manage.py migrate
这个 migrate 命令选中所有还没有执行过的迁移(Django 通过在数据库中创建一个特殊的表 django_migrations 来跟踪执行过哪些迁移)并应用在数据库上 - 也就是将你对模型的更改同步到数据库结构上。
迁移是非常强大的功能,它能让你在开发过程中持续的改变数据库结构而不需要重新删除和创建表 - 它专注于使数据库平滑升级而不会丢失数据。我们会在后面的教程中更加深入的学习这部分内容,现在,你只需要记住,改变模型需要这三步:
编辑 models.py 文件,改变模型。
运行 python manage.py makemigrations 为模型的改变生成迁移文件。
运行 python manage.py migrate 来应用数据库迁移。
数据库迁移被分解成生成和应用两个命令是为了让你能够在代码控制系统上提交迁移数据并使其能在多个应用里使用;这不仅仅会让开发更加简单,也给别的开发者和生产环境中的使用带来方便。
通过阅读文档 Django 后台文档 ,你可以获得关于 manage.py 工具的更多信息。
初试 API
python3 manage.py shell
我们使用这个命令而不是简单的使用 "Python" 是因为 manage.py 会设置 DJANGO_SETTINGS_MODULE 环境变量,这个变量会让 Django 根据 mysite/settings.py 文件来设置 Python 包的导入路径。
当你成功进入命令行后,来试试 database API 吧:
在终端中输入
引用模块
>from polls.models import Choice, Question
列出所有数据值( 未录入, 是空的)
>Question.objects.all()
插入数据
>from django.utils import timezone
>q = Question(question_text="What's new?", pub_date=timezone.now())
保存这条数据
>q.save()
访问这条数据
>q.id
>q.question_text
>q.pub_date
修改数据
>q.question_text = "What's up?"
>q.save()
再次检查数据
>Question.objects.all()
显示`]>`
退出
>exit
给模块扩展自定义函数
polls/models.py
增加
给Question增加
def __str__(self):
return self.question_text
给Choice增加
def __str__(self):
return self.choice_text
这样再列举对象时, 直接显示对象的问题和选择信息
保存后使用shell命令继续调试可得到Question的结果发生了变化
修改前
扩展时间比较功能
polls/models.py
增加两个引用
import datetime
from django.utils import timezone
增加一个函数, 检测是不是最近发布的
def was_published_recently(self):
return self.pub_date >= timezone.now() - datetime.timedelta(days=1)
进入shell命令调试
>from polls.models import Choice, Question
>Question.objects.all()
得到某项数据
>Question.objects.filter(id=1)
//
>from django.utils import timezone
得到当前年份
>current_year = timezone.now().year
检索今年录入的内容
>Question.objects.get(pub_date__year=current_year)
报错, 因为没有id为2的问题
>Question.objects.get(id=2)
pk为primary key, 等同于id
>Question.objects.get(pk=1)
>q = Question.objects.get(pk=1)
调用api
>q.was_published_recently()
列出所有答案 (空)
>q.choice_set.all()
创建投票1
>q.choice_set.create(choice_text='Not much', votes=0)
创建投票2
>q.choice_set.create(choice_text='The sky', votes=0)
>c = q.choice_set.create(choice_text='Just hacking again', votes=0)
>c.question
>q.choice_set.all()
获得所有投票条目数量
>q.choice_set.count()
列出所有今年问题的投票
>Choice.objects.filter(question__pub_date__year=current_year)
找到投票开头为Just的选项
>c = q.choice_set.filter(choice_text__startswith='Just')
删除投票
>c.delete()
创建管理员
python3 manage.py createsuperuser
需要依次输入用户名
, 邮箱
, 密码
进入管理界面
启动服务器
python3 manage.py runserver
进入 http://127.0.0.1:8000/admin/ 页面
向管理页面中加入投票应用
polls/admin.py
from django.contrib import admin
from .models import Question
admin.site.register(Question)
注意事项:
- 这个表单是从问题 Question 模型中自动生成的
- 不同的字段类型(日期时间字段 DateTimeField 、字符字段 CharField)会生成对应的 HTML 输入控件。每个类型的字段都知道它们该如何在管理页面里显示自己。
- 每个日期时间字段 DateTimeField 都有 JavaScript 写的快捷按钮。日期有转到今天(Today)的快捷按钮和一个弹出式日历界面。时间有设为现在(Now)的快捷按钮和一个列出常用时间的方便的弹出式列表。
页面的底部提供了几个选项:
- 保存(Save) - 保存改变,然后返回对象列表。
- 保存并继续编辑(Save and continue editing) - 保存改变,然后重新载入当前对象的修改界面。
- 保存并新增(Save and add another) - 保存改变,然后添加一个新的空对象并载入修改界面。
- 删除(Delete) - 显示一个确认删除页面。
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
from django.urls import path
from . import views
urlpatterns = [
# ex: /polls/
path('', views.index, name='index'),
# ex: /polls/5/
path('/', views.detail, name='detail'),
# ex: /polls/5/results/
path('/results/', views.results, name='results'),
# ex: /polls/5/vote/
path('/vote/', views.vote, name='vote'),
]
然后看看你的浏览器,如果你转到 "/polls/34/" ,Django 将会运行 detail()
方法并且展示你在 URL 里提供的问题 ID。再试试 "/polls/34/vote/" 和 "/polls/34/vote/" ——你将会看到暂时用于占位的结果和投票页。
当某人请求你网站的某一页面时——比如说, "/polls/34/" ,Django 将会载入 mysite.urls
模块,因为这在配置项 ROOT_URLCONF
中设置了。然后 Django 寻找名为 urlpatterns
变量并且按序匹配正则表达式。在找到匹配项 'polls/'
,它切掉了匹配的文本("polls/"
),将剩余文本——"34/"
,发送至 'polls.urls' URLconf 做进一步处理。在这里剩余文本匹配了 '
,使得我们 Django 以如下形式调用 detail()
:
detail(request=
question_id=34 由
为每个 URL 加上不必要的东西,例如 .html ,是没有必要的。不过如果你非要加的话,也是可以的:path('polls/latest.html', views.index),
但是,别这样做,这太傻了。
实现功能
首页显示问题
from .models import Question
def index(request):
latest_question_list = Question.objects.order_by('-pub_date')[:5]
output = ', '.join([q.question_text for q in latest_question_list])
return HttpResponse(output)
这里有个问题:页面的设计写死在视图函数的代码里的。如果你想改变页面的样子,你需要编辑 Python 代码。所以让我们使用 Django 的模板系统,只要创建一个视图,就可以将页面的设计从代码中分离出来。
模版
首先,在你的 polls 目录里创建一个 templates 目录。Django 将会在这个目录里查找模板文件。
你项目的 TEMPLATES 配置项描述了 Django 如何载入和渲染模板。默认的设置文件设置了 DjangoTemplates 后端,并将 APP_DIRS 设置成了 True。这一选项将会让 DjangoTemplates 在每个 INSTALLED_APPS 文件夹中寻找 "templates" 子目录。这就是为什么尽管我们没有像在第二部分中那样修改 DIRS 设置,Django 也能正确找到 polls 的模板位置的原因。
在你刚刚创建的 templates 目录里,再创建一个目录 polls,然后在其中新建一个文件 index.html 。换句话说,你的模板文件的路径应该是 polls/templates/polls/index.html 。因为app_directories
模板加载器是通过上述描述的方法运行的,所以Django可以引用到 polls/index.html 这一模板了。
虽然我们现在可以将模板文件直接放在 polls/templates 文件夹中(而不是再建立一个 polls 子文件夹),但是这样做不太好。Django 将会选择第一个匹配的模板文件,如果你有一个模板文件正好和另一个应用中的某个模板文件重名,Django 没有办法 区分 它们。我们需要帮助 Django 选择正确的模板,最好的方法就是把他们放入各自的 命名空间 中,也就是把这些模板放入一个和 自身 应用重名的子文件夹里。
polls/templates/polls/index.html
{% if latest_question_list %}
{% for question in latest_question_list %}
- {{ question.question_text }}
{% endfor %}
{% else %}
No polls are available.
{% endif %}
polls/views.py
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))
templates
文件夹名字一定不要写错
其中
template = loader.get_template('polls/index.html')
return HttpResponse(template.render(context, request))
可简化为
return render(request, 'polls/index.html', context)
抛出 404 错误
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})
模版 polls/detail.html
{{question.id}}:{{question.question_text}}
一个快捷函数: get_object_or_404()
尝试用 get() 函数获取一个对象,如果不存在就抛出 Http404 错误也是一个普遍的流程。Django 也提供了一个快捷函数,下面是修改后的详情 detail() 视图代码:
polls/views.py
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})
也有 get_list_or_404() 函数,工作原理和 get_object_or_404() 一样,除了 get() 函数被换成了 filter() 函数。如果列表为空的话会抛出 Http404 异常。
使用模板系统
模版 polls/detail.html
{{ question.question_text }}
{% for choice in question.choice_set.all %}
- {{ choice.choice_text }}
{% endfor %}
结合 vue
你会发现index能配置出来, 但是js找不到,
- 创建django项目
- 创建vue项目在manage.py平级
- 配置vue的发布规则, 将静态文件
assetsDir
都放到static下, (vue ui 可以直接界面上修改) -
修改django项目配置
-
settings.py
下的TEMPLATES
的DIRS
要包含vue生成index.html目录, 也就是DIRS
:['vue/dist'], - 添加
STATICFILES_DIRS
格式如下
-
STATICFILES_DIRS = [
os.path.join(BASE_DIR, "vue/dist/static"),
]
- 最后运行django项目
关键点在那两处文件位置设置, 如果dirs设置不正确, 会提示模版找不到, 如果静态目录不是都包含在static下, js会找不到404
参考:
https://segmentfault.com/p/12...
https://ariera.github.io/2017...
http://cncc.bingj.com/cache.a...
http://cncc.bingj.com/cache.a...
https://blog.csdn.net/wjy397/...
http://www.3qphp.com/python/p...