说到web后端框架,其主要是用于提供curd和restapi.有Java的Spring系列,还有现在比较火的Go,js也有一些用于web的库.而python有flask,django和fastapi(重点是提供api).
一点历史
Django 最初被设计用于具有快速开发需求的新闻类站点,目的是要实现简单快捷的网站开发
以下是安装 Django 的推荐方式。
- 安装 pip。最简单的方式是使用 独立 pip 安装器。若你的系统早已安装
pip
,你可能需要更新它,因为它可能过期了。如果它过期了,你会知道的,因为过期的用不了。- 看一下 venv。这个工具提供了隔离的Python环境,比在系统内安装包更实用。它还允许在没有管理员权限的情况下安装包。贡献指南 介绍了如何创建一个虚拟环境。
1 | python -m pip install Django |
当然还要安装数据库和python关于控制数据库的库.1
2
3django-admin startproject myProject
ll
tree myProject
可以看到Django项目还是很简练的,我个人认为Python的很多东西设计都很不错,虽然我对这门语言有点偏见.
manage.py
项目的入口文件
myProject
主目录下的同名子目录,为项目的核心目录,它里面包含配置文件和管理应用的文件。
myProject/__init__.py
每个子目录都会包含这样一个 __init__.py
文件,它是一个空文件,在需要的时候会引入目录下的对象。
myProject/settings.py
配置文件,里面包含对数据库的设置项、CSRF Token 的设置项、模板的设置项等全部设置。
myProject/urls.py
路由控制文件,处理客户端请求,分发到对应的视图函数去处理
myProject/wsgi.py
处理请求和响应.
开始
接下来直接开始1
2cd myProject
python3 manage.py startapp myApp
创建一个名为 myApp 的应用,注意实验环境里不可以创建名为 test 的应用,某些情况下它与 Python 模块冲突
在项目的主目录下出现了名为 myApp 的目录,这就是应用目录。
myApp/admin.py
用于控制后台管理的文件。myApp/apps.py
用于管理应用本身的文件,包括应用的名字如何命名,默认就是 myApp 。myApp/__init__.py
空文件。myApp/migrations
这是用于记录数据库变更信息的目录,Django 中自带的数据库版本控制功能就体现在这个目录,在学习数据存储时会详细介绍。myApp/models.py
创建映射类的文件。myApp/tests.py
编写测试代码的文件。myApp/views.py
创建视图函数的文件,视图函数用于处理客户端发来的请求。
配置应用
在项目的setting.py下增加myApp1
2
3
4
5
6
7
8
9INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
"myApp"
]1
python3 manage.py runserver
开启服务.默认8000端口 更改端口后面直接加端口号.
视图
1 | # myApp/views.py |
映射到url
Examples:
Function views
Add an import: from my_app import views
Add a URL to urlpatterns: path(‘’, views.home, name=’home’)
Class-based views
1.Add an import: from other_app.views import Home
2.Add a URL to urlpatterns: path(‘’, Home.as_view(), name=’home’)
Including another URLconf1.Import the include() function: from django.urls import include, path
2.Add a URL to urlpatterns: path(‘blog/‘, include(‘blog.urls’))
path函数
参数 | 意义 | 是否必须 |
---|---|---|
route | route 是一个匹配 URL 的准则(类似正则表达式)。当 Django 响应一个请求时,它会从 urlpatterns 的第一项开始,按顺序依次匹配列表中的项,直到找到匹配的项。 | 必须 |
view | 当 Django 找到了一个匹配的准则,就会调用这个特定的视图函数,并传入一个 HttpRequest 对象作为第一个参数,被“捕获”的参数以关键字参数的形式传入。 | 必须 |
kwargs | 任意个关键字参数可以作为一个字典传递给目标视图函数。 | 可选 |
name | 为你的 URL 取名能使你在 Django 的任意地方唯一地引用它,尤其是在模板中。这个有用的特性允许你只改一个文件就能全局地修改某个 URL 模式。 | 可选 |
模型
在创建的应用程序中有model1
2
3
4
5
6
7
8# myApp/models.py
from django.db import models
class Book(models.Model):
name = models.CharField(max_length=200)
author = models.CharField(max_length=100)
pub_house = models.CharField(max_length=200)
pub_date = models.DateTimeField('date published')
我觉得这里跟Java Bean有点像.模型是 django.db.models.Model
类的子类。每个模型有一些类变量,它们都表示模型里的一个数据库字段。
每个字段都是 Field
类的实例。比如字符字段是 CharField
,日期字段被表示为 DateTImeField
。这将告诉 Django 每个字段要处理的数据类型。
定义某些 Field
类实例需要参数。如上面的 max_length=100
中的 max_length
。这个参数的用处不止于用来定义数据结构,也用于验证数据。
在setting中修改1
2
3
4
5
6
7
8
9
10
11# myProject/settings.py
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
# 'myApp', 这一注释掉,不注释掉会因重复而报错
'myApp.apps.MyappConfig',
]
然后进行迁移1
python manage.py makemigrations myApp
这样就创建了模型
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19class Migration(migrations.Migration):
initial = True
dependencies = [
]
operations = [
migrations.CreateModel(
name='Book',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=200)),
('author', models.CharField(max_length=100)),
('pub_house', models.CharField(max_length=200)),
('pub_date', models.DateTimeField(verbose_name='date published')),
],
),
]
通过运行 makemigrations
命令,Django 会检测你对模型文件的修改,并且把修改的部分储存为一次迁移.
通过命令查看创建数据库的命令1
python3 manage.py sqlmigrate myApp 0001
模板
默认的设置文件设置了 DjangoTemplates
后端,并设置 APP_DIRS = True
。这一选项将会让 DjangoTemplates
在每个 INSTALLED_APPS
文件夹中寻找 templates 子目录。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [],
'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',
],
},
},
]
在views.py中添加视图1
2
3
4
5
6
7
8
9
10
11
12
13from django.shortcuts import render
from django.http import HttpResponse
from myApp.models import Book
# Create your views here.
def index(requst):
return HttpResponse("Hello World")
def detail(request):
book_list = Book.objects.order_by('pub_date')[:5]
context = {'book_list':book_list}
return render(request,"myApp/detail.html",context)
再进行视图绑定
使用MTV模式实现数据库增删改
首先设计界面.
myApp/templates/myApp/detail.html
里,添加一个表单。1
2
3
4
5
6
7<form action="" method="post" name="addBook">
{% csrf_token %}
<p><span>书名:</span><input type="text" name="name" /></p>
<p><span>作者:</span><input type="text" name="author" /></p>
<p><span>出版社:</span><input type="text" name="pub_house" /></p>
<input type="submit" value="添加" />
</form>
- 上面的模板是输入相应的书名、作者和出版社后,点击添加,将数据存储到数据库并刷新页面显示出来。
- 我们设置表单的
action="/addBook/"
,并设置method="post"
。使用method="post"
(与其相对的是method="get"
)是非常重要的,因为这个提交表单的行为会改变服务器端的数据,无论何时,当你需要创建一个改变服务器端数据的表单时,请使用method="post"
。这不是 Django 的特定技巧,这是优秀的网站开发技巧。 - 由于我们创建一个 POST 表单(它具有修改数据的作用),所以我们需要小心跨站点请求伪造。 但你不必太过担心,因为 Django 已经拥有一个用来防御它的非常容易使用的系统。 简而言之,所有针对内部 URL 的 POST 表单都应该使用
{% csrf_token %}
模板标签
在根 URLconf 中添加命名空间。在 myProject/urls.py
文件中稍作修改,加上 app_name
设置命名空间:1
2
3
4
5
6
7
8
9
10from django.contrib import admin
from django.urls import path
from myApp import views
app_name = 'myApp' # 添加这一行
urlpatterns = [
# path('admin/', admin.site.urls),
path('', views.detail, name='detail'),
path('addBook/', views.addBook, name='addBook'),
]
现在回到 myApp/templates/myApp/detail.html
更改 action
:1
<form action="/addBook/" method="post" name="addBook"></form>
创建 addBook
函数来实现我们添加书籍的功能。
将下面的代码添加到 myApp/views.py:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16# myApp/views.py
from django.http import HttpResponseRedirect
from django.urls import reverse
def addBook(request):
if request.method == 'POST':
temp_name = request.POST['name']
temp_author = request.POST['author']
temp_pub_house = request.POST['pub_house']
from django.utils import timezone
temp_book = Book(name=temp_name, author=temp_author, pub_house=temp_pub_house, pub_date=timezone.now())
temp_book.save()
# 重定向
return HttpResponseRedirect(reverse('detail'))
在 myProject/urls.py 里添加 URL 地址映射:1
2# myProject/urls.py
path('addBook/', views.addBook, name='addBook'),
简单说明:
request.POST
是一个类字典对象,可以通过关键字的名字获取提交的数据。 这个例子中,request.POST['name']
以字符串形式返回name
的值。request.POST
的值永远是字符串。- 在添加书籍之后,代码返回一个
HttpResponseRedirect
而不是常用的HttpResponse
,HttpResponseRedirect
只接收一个参数:用户将要被重定向的 URL。 - 你应该在每次处理 POST 数据时,都返回
HttpResponseRedirect
。这也不是 Django 的特定技巧,这是优秀的网站开发的实践。 - 在这个例子中,我们在
HttpResponseRedirect
的构造函数中使用reverse()
函数。这个函数避免了我们在视图函数中硬编码 URL。它需要我们给出想要跳转的视图的名字和该视图所对应的 URL 模式中需要给该视图提供的参数。reverse()
调用后将返回这样一个字符串:/detail/
。
删除书籍功能实现起来也很简单。
首先,在 myApp/detail.html
中设计我们的模板。1
2
3
4
5
6
7
8
9
10{% for book in book_list.all %}
<tr>
<td>{{ book.name }}</td>
<td>{{ book.author }}</td>
<td>{{ book.pub_house }}</td>
<td>{{ book.pub_date }}</td>
<td><a href="{% url 'delBook' book.id %}">删除</a></td><!--只添加这一行-->
</tr>
{% endfor %}
</table>
可以看出,只需要在每个书籍后面添加一个删除的按钮。删除时也传递了需要删除的图书的 id
。
接着,配置 url,只需在 myProject/urls.py
中添加这一行:1
2# myProject/urls.py
path('delBook/<int:book_id>', views.deleteBook, name='delBook'),
这里 <int:book_id>
是接收传递的参数 book_id
。
最后设计视图函数:1
2
3
4
5
6
7# myApp/views.py
def deleteBook(request, book_id):
bookID = book_id
Book.objects.filter(id=bookID).delete()
# 重定向
return HttpResponseRedirect(reverse('detail'))
这个视图中,获取到 book 的 id,根据 id 来删除指定书籍。最后跟上面的添加书籍函数相同,使用重定位刷新页面。
参考资料
官网这个是中文版的,很详细.
蓝桥云在线平台.