Django快速入门
文章目录
Django是一个高级的Python Web框架,可以快速开发安全和可维护的网站,能解决Web开发过程中常见的任务需求,包括用户认证,内容管理,网站地图,RSS订阅等开箱即用功能。
Django更适用于企业级应用和大型网站的开发。相比之下,Flask更轻量级,更灵活,它只是一个内核,很多功能都是以扩展的形式进行嵌入使用。这使得Flask更适合小型网站和微服务开发。
本文档以一个简单的项目为例对Django进行简单的介绍。
引用
Django 文档 | Django 文档 | Django (djangoproject.com) 👍👍👍:Django的官方文档,教程写得不错
一杯茶的时间,上手 Django 框架开发 - 知乎 (zhihu.com) 👍:一个简单的项目实例,用于快速了解Django(本文档的实例基于该文档的实例)
Django 5.0 release notes | Django documentation | Django (djangoproject.com):Django5.0发布
Django与Flask的比较
Django | Flask | |
---|---|---|
特点 | 大而全 | 小而美 |
适用规模 | 企业级网站开发 | 小型网站和Web服务开发 |
开发体验 | 一站式解决方案 | 随意选自需要的库和工具 |
MTV设计模式
Django框架采用了MTV设计模式,具体而言:
- M(Model):创建数据模型,并执行数据库迁移。即定义数据以什么形式存储
- T(Template):用户界面的模板,接收视图中传入的数据,模板+数据形成完整的用户界面
- V(View):访问数据库,实现业务逻辑,渲染模板,并接入路由表
MTV与MVC的比较如下:
MVC | MTV | |
---|---|---|
数据模型 | Model | Model |
用户界面 | View | Template |
业务逻辑 | Controller | View |
创建项目与app
创建项目
使用django-admin
创建django项目,名为django_news
django-admin startproject django_news
cd django_news
项目文件如下:
django_news // 根目录是项目的容器
├── django_news // 项目全局文件目录
│ ├── __init__.py // 说明这个目录是一个Python包
│ ├── settings.py // django项目全局配置
│ ├── urls.py // 全局路由
│ ├── asgi.py // ASGI服务接口
│ └── wsgi.py // WSGI服务接口
└── manage.py // 项目管理脚本,一个用于与django交互的命令行工具
运行开发服务器:
python manage.py runserver {IP:端口号}
如果不指定IP和端口号,默认为127.0.0.1:8000,此时访问localhost:8000
即可看到欢迎界面。
提示
Django 开发服务器可以保持开启,并且后面修改代码会自动重新加载,非常方便。后面运行其他命令时,再打开一个终端(命令行)即可。
创建app
Django 是一个高度模块化的框架,一个 Django 应用由多个子应用组成,每个子应用称之为 App
- 内置:即 Django 框架自带的应用,包括 admin(后台管理)、auth(身份鉴权)、sessions(会话管理)等等
- 自定义:即用来实现我们自身业务逻辑的应用,这里我们将创建一个新闻展示应用
- 第三方:即社区提供的应用,数量极其丰富,功能涵盖几乎所有方面,能够大大减少开发成本
自定义一个app,命名为news:
python manage.py startapp news
app的文件夹结构如下:
news // news 应用目录
├── __init__.py // 初始化模块
├── admin.py // 后台管理配置
├── apps.py // 应用配置
├── migrations // 数据库迁移文件目录
│ └── __init__.py // 数据库迁移初始化模块
├── models.py // 数据模型
├── tests.py // 单元测试
└── views.py // 视图
将app添加到全局配置,即在django_news/django_news/settings.py
中将new应用加入到INSTALLED_APPS
中:
# ...
INSTALLED_APPS = [
'django.contrib.admin', // 管理员站点
'django.contrib.auth', // 认证授权系统
'django.contrib.contenttypes', // 内容类型框架
'django.contrib.sessions', // 会话框架
'django.contrib.messages', // 消息框架
'django.contrib.staticfiles', // 管理静态文件的框架
'news',
]
视图
Django 中的视图的概念是「一类具有相同功能和模板的网页的集合」
路由系统
用户发送请求,服务器根据请求的地址查找路由表以返回对应的视图。
例如,用户访问http://example.com/apple/buy,然后全局路由根据 /apple/buy 先选择 apple 的路由表,再从 apple 路由表中根据 /buy 选择 /buy 路由,然后执行 /buy 对应的 BuyView 视图,返回给用户结果。
定义Django视图
我们在news/views.py
中编写一个视图如下:
from django.http import HttpResponse
def index(request):
return HttpResponse('Hello World!')
首先创建new/urls.py
,实现news应用的路由表:
from django.urls import path
from . import views
urlpatterns = [
path('index/', views.index, name='index'),
]
每一个 Django 路由表模块(urls.py)中都约定必须包含一个 urlpatterns
列表用来存放路由映射表。列表中每个元素是一个用 django.urls.path
函数封装好的路由映射,通常接收以下三个参数:
route
:必须,即实际的访问路由,空字符串等于/
,即空路由view
:必须,该路由将要访问的视图。name
:可选,该路由的名称,方便后续在模板中使用
将news路由表接入全局路由表,在django_news/urls.py
中修改如下:
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('news/', include('news.urls')),
]
这里用include
接入了news的路由表。
可以看到,如果想要访问视图,需要访问的地址为localhost:8000/news/index
注意
添加路由规则时顺序是很重要的,因为在尝试匹配时会按照从上到下的顺序进行,因此应该把最模糊的路由(即空路由)放在最下面。
模板
模板是网页前端的实现,它是一个文本,用于分离文档的表现形式和内容。
我们可以将模板看成是一个函数,其输入为模板参数,输出为一个页面。
Django 模板语言
Django 模板本质上是一个 HTML 文档,通过一些特殊的语法实现数据的填充。这里介绍最常用的三个语法:
表达式插值
<!-- 单个变量 -->
{{ variable }}
<!-- 获取字典的键或对象的属性 -->
{{ dict.key }}
{{ object.attribute }}
<!-- 获取列表中的某个元素 -->
{{ list.0 }}
条件语句
{% if is_true %}
<h1>It is true!</h1>
{% else %}
<h1>It is false!</h1>
{% endif %}
循环语句
{% for elem in some_list %}
<p>{{ elem }}</p>
{% endfor %}
定义Django模板
创建文件news/templates/news/index.html
注意
要在应用news下面新建一个templates文件夹,再在里面新建一个news文件夹,因为Django 的模板查找机制会将所有应用里面的模板全部收集到一起,如果两个模板的名字冲突,就会导致其中一个模板不能被正确访问。
模板代码如下:
{% if news_list %}
<ul>
{% for elem in news_list %}
<li>
<h3>{{ elem.title }}</h3>
<p>{{ elem.content }}</p>
</li>
{% endfor %}
</ul>
{% else %}
<p>暂无新闻</p>
{% endif %}
完成模板后在视图中对模板进行渲染。在news/views.py
文件中修改如下:
from django.shortcuts import render
def index(request):
context = {
'news_list': [
{
"title": "今天实现了第一个django项目",
"content": "太强了!",
},
{
"title": "今天实现了第二个django项目",
"content": "太强了!",
},
]
}
return render(request, 'news/index.html', context=context)
这里我们调用 django.shortcuts.render
函数来渲染模板,这个函数通常接受三个参数):
request
:请求对象,直接把视图的参数request
传进来就可以template_name
:模板名称,这里就是我们刚刚创建的news/index.html
context
:传入模板的上下文对象,必须是一个字典,字典中的每个键对应模板中的变量。这里我们弄了些假数据,通常来说这里的数据来自数据库。
可以看到,模板分为内容和表现形式两个部分,内容具体指的就是各种变量,而变量需要通过视图进行传参。
模型
django模型也称数据模型,用于定义数据库结构,并执行数据库迁移。ORM对应关系如下:
ORM
ORM 能够代码转换成相应的 SQL 语句从而执行数据库操作,举例如下:
# 查询所有模型
# 等价于 SELECT * FROM Blog
Blog.objects.all()
# 查询单个模型
# 等价于 SELECT * FROM Blog WHERE ID=1
Blog.objects.get(id=1)
# 添加单个模型
# 等价于 INSERT INTO Blog (title, content) VALUES ('hello', 'world')
blog = Blog(title='hello', content='world')
blog.save()
更多的语法请参照模型 | Django 文档 | Django (djangoproject.com)
数据库迁移
数据库迁移是指将用 Django 定义的模型转换成 SQL 代码(即迁移文件),并在数据库中进行建表或更新操作(数据库迁移)
一般的开发流程就是这样:
- 用 Django 定义了一个新的数据模型
- 用
makemigrations
命令创建迁移文件(存储在子应用的 migrations 目录里面) - 用
migrate
命令执行迁移
写给极简主义者
就像之前说的,为了方便大多数项目,我们默认激活了一些应用,但并不是每个人都需要它们。如果你不需要某个或某些应用,你可以在运行
migrate
前毫无顾虑地从INSTALLED_APPS
里注释或者删除掉它们。migrate
命令只会为在INSTALLED_APPS
里声明了的应用进行数据库迁移。
定义Django数据模型
在news/models
中定义数据模型Post:
from django.db import models
class Post(models.Model):
title = models.CharField(max_length=200)
content = models.TextField()
def __str__(self):
return self.title
创建迁移文件:
python manage.py makemigrations {应用名}
执行成功后创建news/migrations/0001_initial.py 迁移脚本。如果不指定应用名,则对所有应用进行操作。
然后进行数据库迁移:
python manage.py migrate
根据django_news/setting.py
文件中的配置,可以修改数据库文件保存的位置:
# Database
# https://docs.djangoproject.com/en/4.2/ref/settings/#databases
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': BASE_DIR / 'db.sqlite3',
}
}
以上是Django的数据库默认配置,将采用sqlite3作为数据库,数据库文件将保存在BASE_DIR / 'db.sqlite3'
配置后台管理接口,将news应用接到后台。在 news/admin.py 中填入代码如下:
from django.contrib import admin
from .models import Post
admin.site.register(Post)
我们创建一个超级用户以访问后台:
python manage.py createsuperuser
访问localhost:8000/admin
登录后,即可看到:
我们可以在news/views.py
中添加数据库查询的代码,这样就可以通过对数据库的访问以向用户呈现数据库的数据了;
from django.shortcuts import render
from .models import Post
def index(request):
context = { 'news_list': Post.objects.all() }
return render(request, 'news/index.html', context=context)
总结
根据上式的实例,我们可以总结django的工作流程如下:
- 接收用户请求并根据url进行路由,寻找对应的视图
- 视图找模型要数据
- 模型找数据库要数据
- 将查到的数据结合模板以html的形式返回给用户
对于程序员,需要编程的主要地方如下:
- models:定义数据库
- views:定义对于数据库数据的提取
- templates:定义用户界面
- urls:配置路由