超级详细的 Python Django Web 入门教程【一文到底】【0基础】【快速上手】
超级详细的 Python Django Web 入门教程【一文到底】【0基础】【快速上手】
Django简介
Django是一个基于Python的Web开发框架,适合初学者快速入门。它遵循MVC设计模式,提供了一套完整的开发组件,包括模型(Model)、视图(View)和模板(Template)。通过Django,你可以轻松地连接数据库、处理HTTP请求、渲染网页等。Django内置了许多安全功能和第三方插件,简化了Web开发流程,让你专注于业务逻辑的实现。只需掌握基本的Python知识,就能快速上手Django,开启你的Web开发之旅。
一、安装 Django
安装Django
pip install django
检查是否安装
pip show django
二、创建Django 项目
1、创建一个 HelloWorld 项目
# 使用Python -m 方式创建Django项目 python -m django startproject [project_name]
示例图:
2、文件说明
|-- HelloWorld | |-- __init__.py | |-- asgi.py | |-- settings.py | |-- urls.py | `-- wsgi.py `-- manage.py
目录说明:
- HelloWorld: 项目的容器。
- manage.py: 一个实用的命令行工具,可让你以各种方式与该 Django 项目进行交互。
- HelloWorld/init.py: 一个空文件,告诉 Python 该目录是一个 Python 包。
- HelloWorld/asgi.py: 一个 ASGI 兼容的 Web 服务器的入口,以便运行你的项目。
- HelloWorld/settings.py: 该 Django 项目的设置/配置。
- HelloWorld/urls.py: 该 Django 项目的 URL 声明; 一份由 Django 驱动的网站"目录"。
- HelloWorld/wsgi.py: 一个 WSGI 兼容的 Web 服务器的入口,以便运行你的项目。
三、VSCode 安装 Django 插件
在 VS Code 使用快捷键 Ctrl + Shift + X ,然后在输入框搜索 Django , 安装 Django 相关的三个插件,后续开发使用。
四、启动Django项目
启动项目
python manage.py runserver # 启动项目 带端口号和IP python manage.py runserver 0.0.0.0:8000
0.0.0.0 让其它电脑可连接到开发服务器,8000 为端口号。如果不说明,那么端口号默认为 8000。 在浏览器输入你服务器的 ip(这里我们输入本机 IP 地址: 127.0.0.1:8000) 及端口号,如果正常启动,输出结果如下:
五、视图和 URL 配置
在先前创建的 HelloWorld 目录下的 HelloWorld 目录新建一个 views.py 文件,并输入代码:
HelloWorld/HelloWorld/views.py 文件代码:
from django.http import HttpResponse def hello(request): return HttpResponse("Hello world ! ")
接着,绑定 URL 与视图函数。打开 urls.py 文件,删除原来代码,将以下代码复制粘贴到 urls.py 文件中:
HelloWorld/HelloWorld/urls.py 文件代码:
from django.urls import path from . import views urlpatterns = [ path("", views.hello, name="hello"), ]
整个目录结构如下:
|-- HelloWorld | |-- __init__.py | |-- __init__.pyc | |-- settings.py | |-- settings.pyc | |-- urls.py # url 配置 | |-- urls.pyc | |-- views.py # 添加的视图文件 | |-- views.pyc # 编译后的视图文件 | |-- wsgi.py | `-- wsgi.pyc `-- manage.py
完成后,启动 Django 开发服务器,并在浏览器访问打开浏览器并访问:
我们也可以修改以下规则:
HelloWorld/HelloWorld/urls.py 文件代码: from django.urls import path from . import views urlpatterns = [ path('hello/', views.hello), ]
通过浏览器打开 http://127.0.0.1:8000/hello,输出结果如下:
注意:项目中如果代码有改动,服务器会自动监测代码的改动并自动重新载入,所以如果你已经启动了服务器则不需手动重启。
path() 函数
Django path() 可以接收四个参数,分别是两个必选参数:route、view 和两个可选参数:kwargs、name。语法格式:
path(route, view, kwargs=None, name=None)
- route:字符串,定义 URL 的路径部分。可以包含变量,例如 int:my_variable,以从 URL 中捕获参数并将其传递给视图函数。
- view:视图函数,处理与给定路由匹配的请求。可以是一个函数或一个基于类的视图。
- kwargs(可选):一个字典,包含传递给视图函数的额外关键字参数。
- name(可选): 为 URL 路由指定一个唯一的名称,以便在代码的其他地方引用它。这对于在模板中生成 URL 或在代码中进行重定向等操作非常有用。
Django2. 0中可以使用 re_path() 方法来兼容 1.x 版本中的 url() 方法,一些正则表达式的规则也可以通过 re_path() 来实现 。
from django.urls import include, re_path urlpatterns = [ re_path(r'^index/$', views.index, name='index'), re_path(r'^bio/(?P\w+)/$', views.bio, name='bio'), re_path(r'^weblog/', include('blog.urls')), ... ]
六、Django 模板
1、创建第一个Django 模板
在上一章节中我们使用 django.http.HttpResponse() 来输出 “Hello World!”。该方式将数据与视图混合在一起,不符合 Django 的 MVC 思想。
本章节我们将为大家详细介绍 Django 模板的应用,模板是一个文本,用于分离文档的表现形式和内容。
模板应用实例:
我们接着上一章节的项目将在 HelloWorld 目录底下创建 templates 目录并建立 runoob.html文件,整个目录结构如下:
HelloWorld/ |-- HelloWorld | |-- __init__.py | |-- __init__.pyc | |-- settings.py | |-- settings.pyc | |-- urls.py | |-- urls.pyc | |-- views.py | |-- views.pyc | |-- wsgi.py | `-- wsgi.pyc |-- manage.py `-- templates `-- runoob.html
runoob.html 文件代码如下:
HelloWorld/templates/runoob.html 文件代码:
{{ hello }}
从模板中我们知道变量使用了双括号。
接下来我们需要向Django说明模板文件的路径,修改HelloWorld/settings.py,先导入 os 依赖 import os ,然后修改 TEMPLATES 中的 DIRS 为 [os.path.join(BASE_DIR, ‘templates’)],如下所示:
HelloWorld/HelloWorld/settings.py 文件代码:
# 先导入 os 依赖 import os # 修改 TEMPLATES 中的 DIRS 为 [os.path.join(BASE_DIR, 'templates')] TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [os.path.join(BASE_DIR, 'templates')], # 修改位置 '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,增加一个新的对象,用于向模板提交数据:
HelloWorld/HelloWorld/views.py 文件代码:
from django.shortcuts import render def runoob(request): context = {} context['hello'] = 'Hello World!' return render(request, 'runoob.html', context)
HelloWorld/HelloWorld/urls.py 文件代码:
from django.urls import path from . import views urlpatterns = [ path('runoob/', views.runoob), ]
可以看到,我们这里使用 render 来替代之前使用的 HttpResponse。render 还使用了一个字典 context 作为参数。
context 字典中元素的键值 hello 对应了模板中的变量 {{ hello }}。
再次访问 http://127.0.0.1:8000/runoob,可以看到页面:
这样我们就完成了使用模板来输出数据,从而实现数据与视图分离。
接下来我们将具体介绍模板中常用的语法规则。
2、Django 模板标签
变量
模板语法:
view:{"HTML变量名" : "views变量名"} HTML:{{变量名}}
HelloWorld/HelloWorld/views.py 文件代码:
from django.shortcuts import render def runoob(request): views_name = "Hello World!" return render(request,"runoob.html", {"name":views_name})
templates 中的 runoob.html :
Hello World!
{{ name }}
再次访问 http://127.0.0.1:8000/runoob,可以看到页面:
列表
templates 中的 runoob.html中,可以用 . 索引下标取出对应的元素。
HelloWorld/HelloWorld/views.py 文件代码:
from django.shortcuts import render def runoob(request): views_list = ["Hello World 1","Hello World 2","Hello World 3"] return render(request, "runoob.html", {"views_list": views_list})
HelloWorld/templates/runoob.html 文件代码:
Hello World!
{{ views_list }}
# 取出整个列表{{ views_list.0 }}
# 取出列表的第一个元素再次访问 http://127.0.0.1:8000/runoob,可以看到页面:
字典
templates 中的 runoob.html中,可以用 .键 取出对应的值。
HelloWorld/HelloWorld/views.py 文件代码:
from django.shortcuts import render def runoob(request): views_dict = {"name":"Hello World!"} return render(request, "runoob.html", {"views_dict": views_dict})
HelloWorld/templates/runoob.html 文件代码:
Hello World!
{{ views_dict }}
{{ views_dict.name }}
再次访问 http://127.0.0.1:8000/runoob,可以看到页面:
过滤器
模板语法:
{{ 变量名 | 过滤器:可选参数 }}
模板过滤器可以在变量被显示前修改它,过滤器使用管道字符,如下所示:
{{ name|lower }}
{{ name }} 变量被过滤器 lower 处理后,文档大写转换文本为小写。
过滤管道可以被 套接 ,既是说,一个过滤器管道的输出又可以作为下一个管道的输入:**
{{ my_list|first|upper }}
以上实例将第一个元素并将其转化为大写。
有些过滤器有参数。 过滤器的参数跟随冒号之后并且总是以双引号包含。 例如:
{{ bio|truncatewords:"30" }}
这个将显示变量 bio 的前30个词。
其他过滤器:
- addslashes : 添加反斜杠到任何反斜杠、单引号或者双引号前面。
- date : 按指定的格式字符串参数格式化 date 或者 datetime 对象,
实例:
{{ pub_date|date:"F j, Y" }}
- length : 返回变量的长度。
default
- default 为变量提供一个默认值。
- 如果 views 传的变量的布尔值是 false,则使用指定的默认值。
以下值为 false:
0 0.0 False 0j "" [] () set() {} None
HelloWorld/HelloWorld/views.py 文件代码:
from django.shortcuts import render def runoob(request): name =0 return render(request, "runoob.html", {"name": name})
HelloWorld/templates/runoob.html 文件代码:
{{ name|default:"Hello World! 666" }}
再次访问 http://127.0.0.1:8000/runoob,可以看到页面:
length
返回对象的长度,适用于字符串和列表。
字典返回的是键值对的数量,集合返回的是去重后的长度。
HelloWorld/HelloWorld/views.py 文件代码:
from django.shortcuts import render def runoob(request): name ="Hello World! " return render(request, "runoob.html", {"name": name})
HelloWorld/templates/runoob.html 文件代码:
Hello World! {{ name|length}}
再次访问 http://127.0.0.1:8000/runoob,可以看到页面:
filesizeformat
- 以更易读的方式显示文件的大小(即’13 KB’, ‘4.1 MB’, '102 bytes’等)。
- 字典返回的是键值对的数量,集合返回的是去重后的长度。
HelloWorld/HelloWorld/views.py 文件代码:
from django.shortcuts import render def runoob(request): num=1024 return render(request, "runoob.html", {"num": num})
HelloWorld/templates/runoob.html 文件代码:
Hello World! {{ num|filesizeformat}}
再次访问 http://127.0.0.1:8000/runoob,可以看到页面:
date
- 根据给定格式对一个日期变量进行格式化。
- 格式 Y-m-d H:i:s返回 年-月-日 小时:分钟:秒 的格式时间。
HelloWorld/HelloWorld/views.py 文件代码:
from django.shortcuts import render def runoob(request): import datetime now =datetime.datetime.now() return render(request, "runoob.html", {"time": now})
HelloWorld/templates/runoob.html 文件代码:
{{ time|date:"Y-m-d" }}
再次访问 http://127.0.0.1:8000/runoob,可以看到页面:
truncatechars
如果字符串包含的字符总个数多于指定的字符数量,那么会被截断掉后面的部分。
截断的字符串将以 … 结尾。
HelloWorld/HelloWorld/views.py 文件代码:
from django.shortcuts import render def runoob(request): views_str = "Hello World!" return render(request, "runoob.html", {"views_str": views_str})
HelloWorld/templates/runoob.html 文件代码:
{{ views_str|truncatechars:2}}
再访问访问 http://127.0.0.1:8000/runoob,可以看到页面:
safe
- 将字符串标记为安全,不需要转义。
- 要保证 views.py 传过来的数据绝对安全,才能用 safe。
- 和后端 views.py 的 mark_safe 效果相同。
- Django 会自动对 views.py 传到HTML文件中的标签语法进行转义,令其语义失效。加 safe 过滤器是告诉 Django 该数据是安全的,不必对其进行转义,可以让该数据语义生效。
HelloWorld/HelloWorld/views.py 文件代码:
from django.shortcuts import render def runoob(request): views_str = "点击跳转" return render(request, "runoob.html", {"views_str": views_str})
HelloWorld/templates/runoob.html 文件代码:
{{ views_str|safe }}
再访问访问 http://127.0.0.1:8000/runoob,可以看到页面:
if/else 标签
基本语法格式如下:
{% if condition %} ... display {% endif %}
或者:
{% if condition1 %} ... display 1 {% elif condition2 %} ... display 2 {% else %} ... display 3 {% endif %}
根据条件判断是否输出。if/else 支持嵌套。
{% if %} 标签接受 and , or 或者 not 关键字来对多个变量做判断 ,或者对变量取反( not ),例如: {% if athlete_list and coach_list %} athletes 和 coaches 变量都是可用的。 {% endif %}
HelloWorld/HelloWorld/views.py 文件代码:
from django.shortcuts import render def runoob(request): views_num = 88 return render(request, "runoob.html", {"num": views_num})
HelloWorld/templates/runoob.html 文件代码:
Hello World! {%if num > 90 and num % elif num 60 and num % else %} 一边玩去~ {% endif %} % for athlete in athlete_list %} { athlete.name }}% endfor %} "views_list": views_list}) % for i in views_list %} { i }}% endfor %} % for athlete in athlete_list reversed %} ... {% endfor %} % for i in views_list reversed%} { i }}% endfor %} "name":"Hello World","age":18} return render(request, "runoob.html", {"views_dict": views_dict}) % for i,j in views_dict.items %} {{ i }}---{{ j }} {% endfor %} {forloop}} 变量获取循环序号。"listvar": views_list}) % for i in listvar %} {{ forloop.counter }} {{ forloop.counter0 }} {{ forloop.revcounter }} {{ forloop.revcounter0 }} {{ forloop.first }} {{ forloop.last }} {% endfor %} "listvar": views_list}) % for i in listvar %} % for i in listvar %} {{ forloop.counter0 }} {% empty %} 空空如也~ {% endfor %} % for athlete in athlete_list %} { athlete.name }}% for sport in athlete.sports_played %} { sport }}% endfor %} % endfor %} # 这是一个注释 #} % include %} 标签允许在模板中包含其它的模板的内容。 下面这个例子都包含了 nav.html 模板: {% include "nav.html" %} 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [BASE_DIR, "/templates",], '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', ], "libraries":{ # 添加这边三行配置 'my_tags':'templatetags.my_tags' # 添加这边三行配置 } # 添加这边三行配置 }, }, ] ... % load my_tags %} { 11|my_filter:22 }} % my_tag1 11 22 33 %} % load my_tags %} { 11|my_filter:22 }} {% my_tag1 11 22 33 %} % my_html "zzz" "xxx" %} % load my_tags %} % my_html "zzz" "xxx" %} "name": name}) % load static %} {name}}% block 名称 %} 预留给子模板的区域,可以设置设置默认内容 {% endblock 名称 %} % extends "父模板路径"%} % block 名称 % } 内容 {% endblock 名称 %} % block mainbody %} % endblock %} %extends "base.html" %} {% block mainbody %} % endblock %} 'default': { 'ENGINE': 'django.db.backends.mysql', # 数据库引擎 'NAME': 'runoob', # 数据库名称 'HOST': '127.0.0.1', # 数据库地址,本机 ip 地址 127.0.0.1 'PORT': 3306, # 端口 'USER': 'root', # 数据库用户名 'PASSWORD': '123456', # 数据库密码 } } % csrf_token %} { rlt }}} if request.POST: ctx['rlt'] = request.POST['q'] return render(request, "post.html", ctx) 'legend_data': ['苹果', '香蕉', '樱桃', '橘子'], 'series_data': [ {value: 15, name: '苹果'}, {value: 30, name: '香蕉'}, {value: 45, name: '樱桃'}, {value: 10, name: '橘子'} ] } return render(request, 'echarts_pie_chart.html', {'chart_data': data}) "echartsPieChart" style="width: 600px;height:400px;" // 获取 Django 视图传递的数据 var chartData = {{ chart_data|safe }}; // 基于准备好的dom,初始化echarts实例 var myChart = echarts.init(document.getElementById('echartsPieChart')); // 指定图表的配置项和数据 var option = { title: { text: 'ECharts 饼图示例', left: 'center' }, tooltip: { trigger: 'item', formatter: '{a}
{b} : {c} ({d}%)' }, legend: { orient: 'vertical', left: 'left', data: chartData.legend_data }, series: [ { name: '访问来源', type: 'pie', radius: '55%', center: ['50%', '60%'], // 使用 Django 传递的数据 data: chartData.series_data, emphasis: { itemStyle: { shadowBlur: 10, shadowOffsetX: 0, shadowColor: 'rgba(0, 0, 0, 0.5)' } } } ] }; // 使用刚指定的配置项和数据显示图表。 myChart.setOption(option);这里也可以将Data 改为动态{% for item in pie_data %} 加载
ECharts 饼图 "echartsPieChart" style="width: 600px;height:400px;"> // 获取 Django 视图传递的数据 var chartData = {{ chart_data|safe }}; // 基于准备好的dom,初始化echarts实例 var myChart = echarts.init(document.getElementById('echartsPieChart')); // 指定图表的配置项和数据 var option = { title: { text: 'ECharts 饼图示例', left: 'center' }, tooltip: { trigger: 'item', formatter: '{a}
{b} : {c} ({d}%)' }, legend: { orient: 'vertical', left: 'left', data: chartData.legend_data }, series: [ { name: '访问来源', type: 'pie', radius: '55%', center: ['50%', '60%'], data: [ // 使用 Django 传递的数据 {% for item in pie_data %} {value: {{ item.value }}, name: '{{ item.name }}'}, {% endfor %} ], emphasis: { itemStyle: { shadowBlur: 10, shadowOffsetX: 0, shadowColor: 'rgba(0, 0, 0, 0.5)' } } } ] }; // 使用刚指定的配置项和数据显示图表。 myChart.setOption(option);4. 创建 Django 路由
urls.py from django.contrib import admin from django.urls import path , include,re_path from . import views ,testdb,search,search2 ,charts urlpatterns = [ path('echarts-pie-chart/', charts.echarts_pie_chart_view), ]
5. 运行结果
访问 http://127.0.0.1:8000/echarts-pie-chart/ 显示结果如下:
十、Django + Openyxl + ECharts
1: 安装所需的库
首先,确保安装了 pandas 和 openpyxl 库,这些库将帮助您读取 Excel 文件。
pip install pandas openpyxl
2: 创建 Django 视图来处理 Excel 文件上传
在您的 Django 视图中,添加一个函数来处理上传的 Excel 文件,并使用 pandas 读取数据。
views.py
# views.py from django.shortcuts import render def upload_excel(request): return render(request, 'upload_excel.html') models.py # models.py import pandas as pd from django.http import JsonResponse from django.views.decorators.csrf import csrf_exempt @csrf_exempt def import_excel(request): if request.method == 'POST': excel_file = request.FILES['file'] df = pd.read_excel(excel_file, engine='openpyxl') # 假设您的 Excel 文件有两列:'Category' 和 'Value' data = df.to_dict(orient='records') # 转换数据格式以适配 ECharts echarts_data = [] for item in data: echarts_data.append({ 'name': item['Category'], 'value': item['Value'] }) return JsonResponse(echarts_data, safe=False) else: return JsonResponse({'error': 'Invalid request'}, status=400)
3: 配置 URL 模式
在 urls.py 中添加一个 URL 模式来处理 Excel 文件上传。
# urls.py from django.urls import path from .views import import_excel,upload_excel urlpatterns = [ path('upload_excel/', upload_excel), path('import_excel/', import_excel, name='import_excel'), ]
4: 创建 HTML 表单以上传 Excel 文件
在您的 HTML 模板中,添加一个表单来上传 Excel 文件。
{% csrf_token %} "echarts-pie" style="width: 600px;height:400px;"> document.querySelector('form').onsubmit = function(event) { event.preventDefault(); var formData = new FormData(this); fetch('{% url 'import_excel' %}', { method: 'POST', body: formData, headers: { 'X-CSRFToken': '{{ csrf_token }}' } }) .then(response => response.json()) .then(data => { // 初始化 ECharts 饼图 var myChart = echarts.init(document.getElementById('echarts-pie')); var option = { series: [{ type: 'pie', data: data }] }; myChart.setOption(option); }) .catch(error => console.error('Error:', error)); };
5: 启动 Django 服务器并测试
启动 Django 服务器,并在浏览器中访问 http://127.0.0.1:8000/report/upload_excel/ , 您创建的 HTML 页面。上传一个 Excel 文件,您应该会看到 ECharts 饼图显示上传的数据。
- length : 返回变量的长度。