超级详细的 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<username>\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 文件代码:
<h1>{{ hello }}</h1>

从模板中我们知道变量使用了双括号。

接下来我们需要向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 :

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Hello World!</title>
    </head>
    <body>
        <p>{{ name }}</p>
    </body>
</html>

再次访问 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 文件代码:

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Hello World!</title>
    </head>
    <body>
        <p>{{ views_list }}</p>   # 取出整个列表
        <p>{{ views_list.0 }}</p> # 取出列表的第一个元素
    </body>
</html>

再次访问 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 文件代码:

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Hello World!</title>
    </head>
    <body>
        <p>{{ views_dict }}</p>
        <p>{{ views_dict.name }}</p>
    </body>
</html>

再次访问 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 文件代码:

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Hello World!</title>
    </head>
    <body>
        {{ name|length}}
    </body>
</html>

再次访问 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 文件代码:

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Hello World!</title>
    </head>
    <body>
        {{ num|filesizeformat}}
    </body>
</html>

再次访问 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 = "<a href='https://www.runoob.com/'>点击跳转</a>"
    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 文件代码:

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Hello World!</title>
    </head>
    <body>
        {%if num > 90 and num <= 100 %}
            优秀
        {% elif num > 60 and num <= 90 %}
            合格
        {% else %}
            一边玩去~
        {% endif %}
    </body>
</html>

再访问访问 http://127.0.0.1:8000/runoob,可以看到页面:

在这里插入图片描述

for 标签

{% for %} 允许我们在一个序列上迭代。

与 Python 的 for 语句的情形类似,循环语法是 for X in Y ,Y 是要迭代的序列而 X 是在每一个特定的循环中使用的变量名称。

每一次循环中,模板系统会渲染在 {% for %} 和 {% endfor %} 之间的所有内容。例如,给定一个运动员列表 athlete_list 变量,我们可以使用下面的代码来显示这个列表:

<ul>
    {% for athlete in athlete_list %}
        <li>{{ athlete.name }}</li>
    {% endfor %}
</ul>

HelloWorld/HelloWorld/views.py 文件代码:

from django.shortcuts import render

def runoob(request):
    views_list = ["Django教程","Django教程1","Django教程2","Django教程3",]
    return render(request, "runoob.html", {"views_list": views_list})

HelloWorld/templates/runoob.html 文件代码:

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Hello World!</title>
    </head>
    <body>
        <ul>
            {% for i in views_list %}
                <li>{{ i }}</li>
            {% endfor %}
        </ul>
    </body>
</html>

再访问访问 http://127.0.0.1:8000/runoob,可以看到页面:

在这里插入图片描述

给标签增加一个 reversed 使得该列表被反向迭代:

{% for athlete in athlete_list reversed %}
...
{% endfor %}

HelloWorld/templates/runoob.html 文件代码:

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Hello World!</title>
    </head>
    <body>
        <ul>
            {% for i in views_list  reversed%}
                <li>{{ i }}</li>
            {% endfor %}            
        </ul>
    </body>
</html>

再访问访问 http://127.0.0.1:8000/runoob,可以看到页面:

在这里插入图片描述

遍历字典

遍历字典: 可以直接用字典 .items 方法,用变量的解包分别获取键和值。

HelloWorld/HelloWorld/views.py 文件代码:

from django.shortcuts import render

def runoob(request):
    views_dict = {"name":"Hello World","age":18}
    return render(request, "runoob.html", {"views_dict": views_dict})

HelloWorld/templates/runoob.html 文件代码:

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Hello World!</title>
    </head>
    <body>
        <ul>
            {% for i,j in views_dict.items %}
                {{ i }}---{{ j }}
            {% endfor %}                      
        </ul>
    </body>
</html>

再访问访问 http://127.0.0.1:8000/runoob,可以看到页面:

在这里插入图片描述

在 {% for %} 标签里可以通过 {{forloop}} 变量获取循环序号。

  • forloop.counter: 顺序获取循环序号,从 1 开始计算
  • forloop.counter0: 顺序获取循环序号,从 0 开始计算
  • forloop.revcounter: 倒序获取循环序号,结尾序号为 1
  • forloop.revcounter0: 倒序获取循环序号,结尾序号为 0
  • forloop.first(一般配合if标签使用): 第一条数据返回 True,其他数据返回 False
  • forloop.last(一般配合if标签使用): 最后一条数据返回 True,其他数据返回 False

HelloWorld/HelloWorld/views.py 文件代码:

from django.shortcuts import render

def runoob(request):
     views_list = ["a", "b", "c", "d", "e"]
     return render(request, "runoob.html", {"listvar": views_list})

HelloWorld/templates/runoob.html 文件代码:

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Hello World!</title>
    </head>
    <body>
        <ul>
            {% for i in listvar %}
                {{ forloop.counter }}
                {{ forloop.counter0 }}
                {{ forloop.revcounter }}
                {{ forloop.revcounter0 }}
                {{ forloop.first }}
                {{ forloop.last }}
            {% endfor %}                              
        </ul>
    </body>
</html>

再访问访问 http://127.0.0.1:8000/runoob,可以看到页面:

在这里插入图片描述

{% empty %}

   可选的 {% empty %} 从句:在循环为空的时候执行(即 in 后面的参数布尔值为 False )。

HelloWorld/HelloWorld/views.py 文件代码:

from django.shortcuts import render

def runoob(request):
  views_list = []
  return render(request, "runoob.html", {"listvar": views_list})

HelloWorld/templates/runoob.html 文件代码:

{% for i in listvar %}
    <!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Hello World!</title>
    </head>
    <body>
        <ul>
            {% for i in listvar %}
                {{ forloop.counter0 }}
            {% empty %}
                空空如也~
            {% endfor %}                                                      
        </ul>
    </body>
</html>

再访问访问 http://127.0.0.1:8000/runoob,可以看到页面:

在这里插入图片描述

可以嵌套使用 {% for %} 标签:

{% for athlete in athlete_list %}
    <h1>{{ athlete.name }}</h1>
    <ul>
    {% for sport in athlete.sports_played %}
        <li>{{ sport }}</li>
    {% endfor %}
    </ul>
{% endfor %}

注释标签

Django 注释使用 {# #}。

{# 这是一个注释 #}

include 标签

{% include %} 标签允许在模板中包含其它的模板的内容。
下面这个例子都包含了 nav.html 模板:
{% include "nav.html" %}

csrf_token

csrf_token 用于form表单中,作用是跨站请求伪造保护。

如果不用{% csrf_token %}标签,在用 form 表单时,要再次跳转页面会报 403 权限错误。
用了{% csrf_token %} 标签,在 form 表单提交数据时,才会成功。

解析:

  • 首先,向服务器发送请求,获取登录页面,此时中间件 csrf 会自动生成一个隐藏input标签,该标签里的 value 属性的值是一个随机的字符串,用户获取到登录页面的同时也获取到了这个隐藏的input标签。

  • 然后,等用户需要用到form表单提交数据的时候,会携带这个 input 标签一起提交给中间件 csrf,原因是 form 表单提交数据时,会包括所有的 input 标签,中间件 csrf 接收到数据时,会判断,这个随机字符串是不是第一次它发给用户的那个,如果是,则数据提交成功,如果不是,则返回403权限错误。

自定义标签和过滤器

1、在应用目录下创建 templatetags 目录(与 templates 目录同级,目录名只能是 templatetags)。

HelloWorld/
|-- HelloWorld
|   |-- __init__.py
|   |-- __init__.pyc
|   |-- settings.py
...
|-- manage.py
`-- templatetags
`-- templates

2、在 templatetags 目录下创建任意 py 文件,如:my_tags.py。
3、my_tags.py 文件代码如下:

from django import template

register = template.Library()   #register的名字是固定的,不可改变

@register.filter(name='cut_string')
def cut_string(value, arg):
    """Removes all values of "arg" from the string"""
    return value.replace(arg, '')

@register.filter
def my_filter(v1, v2):
    return v1 * v2


@register.simple_tag
def my_tag1(v1, v2, v3):
    return v1 * v2 * v3

修改 settings.py 文件的 TEMPLATES 选项配置,添加 libraries 配置:

settings.py 配置文件...
TEMPLATES = [
    {
        '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'   # 添加这边三行配置        
            }                                      # 添加这边三行配置
        },
    },
]
...

在这里插入图片描述

4、利用装饰器 @register.filter 自定义过滤器。

注意:装饰器的参数最多只能有 2 个。

@register.filter
def my_filter(v1, v2):
    return v1 * v2

5、利用装饰器 @register.simple_tag 自定义标签。

@register.simple_tag
def my_tag1(v1, v2, v3):
    return v1 * v2 * v3

6、在使用自定义标签和过滤器前,要在 html 文件 body 的最上方中导入该 py 文件。

{% load my_tags %}

7、在 HTML 中使用自定义过滤器。

{{ 11|my_filter:22 }}

8、在 HTML 中使用自定义标签。

{% my_tag1 11 22 33 %}

6、7、8,完整代码:

runoob.html 文件代码如下:

{% load my_tags %}
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Hello World!</title>
       
    </head>
    <body>
            {{ 11|my_filter:22 }}
            {% my_tag1 11 22 33 %}
    </body>
</html>

在这里插入图片描述

9、语义化标签
在该 py 文件中导入 mark_safe。

from django.utils.safestring import mark_safe

定义标签时,用上 mark_safe 方法,令标签语义化,相当于 jQuery 中的 html() 方法。
和前端HTML文件中的过滤器 safe 效果一样。

@register.simple_tag
def my_html(v1, v2):
    temp_html = "<input type='text' id='%s' class='%s' />" %(v1, v2)
    return mark_safe(temp_html)

my_tags.py 文件完整代码如下:

from django import template
from django.utils.safestring import mark_safe

register = template.Library()   #register的名字是固定的,不可改变

@register.simple_tag
def my_html(v1, v2):
    temp_html = "<input type='text' id='%s' class='%s' />" %(v1, v2)
    return mark_safe(temp_html)

在HTML中使用该自定义标签,在页面中动态创建标签。

{% my_html "zzz" "xxx" %}

完整代码:

{% load my_tags %}
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Hello World!</title>
       
    </head>
    <body>
            {% my_html "zzz" "xxx" %}
    </body>
</html>

在这里插入图片描述

配置静态文件

1、在项目根目录下创建 statics 目录。

在这里插入图片描述

目录结构

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
`-- statics
|   `-- css
|   `-- images
|   `-- js
|   `-- plugins

2、在 settings 文件的最下方配置添加以下配置:

STATIC_URL = '/static/' # 别名 
STATICFILES_DIRS = [ 
    os.path.join(BASE_DIR, "statics"), 
]

在这里插入图片描述

3、在 statics 目录下创建 css 目录,js 目录,images 目录,plugins 目录, 分别放 css文件,js文件,图片,插件。
4、把 bootstrap 框架放入插件目录 plugins。
5、在 HTML 文件的 head 标签中引入 bootstrap。

注意:此时引用路径中的要用配置文件中的别名 static,而不是目录 statics。

<link rel="stylesheet" href="/static/plugins/bootstrap-3.3.7/dist/css/bootstrap.css">

在模板中使用需要加入 {% load static %} 代码,以下实例我们从静态目录中引入图片。

HelloWorld/HelloWorld/views.py 文件代码:

from django.shortcuts import render

def runoob(request):
    name ="Django教程"
    return render(request, "runoob.html", {"name": name})

HelloWorld/templates/runoob.html 文件代码:

{% load static %}
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Hello World!</title>
        <link rel="stylesheet" href="/static/plugins/bootstrap-3.3.7/dist/css/bootstrap.css">
    </head>
    <body>
           {{name}}<img src="{% static 'images/runoob-logo.png' %}" alt="runoob-logo">
    </body>
</html>

再访问访问 http://127.0.0.1:8000/runoob,可以看到页面:

在这里插入图片描述

模板继承

模板可以用继承的方式来实现复用,减少冗余内容。
网页的头部和尾部内容一般都是一致的,我们就可以通过模板继承来实现复用。
父模板用于放置可重复利用的内容,子模板继承父模板的内容,并放置自己的内容。

目录结构

HelloWorld/
|-- HelloWorld
|   |-- __init__.py
|   |-- settings.py
|   |-- urls.py
|   |-- views.py
|   |-- wsgi.py
|-- manage.py
|-- templates
|   `-- base.html
|   `-- runoob.html

父模板

标签 block…endblock: 父模板中的预留区域,该区域留给子模板填充差异性的内容,不同预留区域名字不能相同。

{% block 名称 %} 
预留给子模板的区域,可以设置设置默认内容
{% endblock 名称 %}

子模板

子模板使用标签 extends 继承父模板:

{% extends "父模板路径"%} 

子模板如果没有设置父模板预留区域的内容,则使用在父模板设置的默认内容,当然也可以都不设置,就为空。

子模板设置父模板预留区域的内容:

{ % block 名称 % }
内容 
{% endblock 名称 %}

接下来我们先创建之前项目的 templates 目录中添加 base.html 文件,代码如下:

HelloWorld/templates/base.html 文件代码:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Django教程(runoob.com)</title>
</head>
<body>
    <h1>Hello World!</h1>
    <p>Django教程 Django 测试。</p>
    {% block mainbody %}
       <p>original</p>
    {% endblock %}
</body>
</html>

以上代码中,名为 mainbody 的 block 标签是可以被继承者们替换掉的部分。
所有的 {% block %} 标签告诉模板引擎,子模板可以重载这些部分。
runoob.html 中继承 base.html,并替换特定 block,runoob.html 修改后的代码如下:

HelloWorld/templates/runoob.html 文件代码:

{%extends "base.html" %}
 
{% block mainbody %}
<p>继承了 base.html 文件</p>
{% endblock %}

在这里插入图片描述

第一行代码说明 runoob.html 继承了 base.html 文件。可以看到,这里相同名字的 block 标签用以替换 base.html 的相应 block。

重新访问地址 http://127.0.0.1:8000/runoob,输出结果如下:

在这里插入图片描述

七、Django 模型

定义模型

创建 APP

Django 规定,如果要使用模型,必须要创建一个 app。我们使用以下命令创建一个 TestModel 的 app:

python manage.py startapp TestModel

目录结构如下:

HelloWorld
|-- HelloWorld
|   |-- __init__.py
|   |-- asgi.py
|   |-- settings.py
|   |-- urls.py
|   |-- wsgi.py
|-- TestModel
|   |-- __init__.py
|   |-- admin.py
|   |-- apps.py
|   |-- models.py
|   |-- tests.py
|   `-- views.py
|-- manage.py

在这里插入图片描述

使用 APP 实现 视图和 URL 配置

1、TestModel.views.py

from django.shortcuts import render
from django.http import HttpResponse

# Create your views here.
def test(request):
    return HttpResponse("hello django")

2、TestModel.urls.py

from django.urls import path
from TestModel import views

urlpatterns = [
    path('test/', views.test)
]

3、HelloWorld.urls.py

from django.contrib import admin
from django.urls import path , include

urlpatterns = [
    path('admin/', admin.site.urls),
    path("",include("TestModel.urls")),
]

4、HelloWorld.settings.py

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'TestModel.apps.TestmodelConfig'
]

在这里插入图片描述

5、运行结果

在这里插入图片描述

配置数据库

安装 驱动 与配置

Django 对各种数据库提供了很好的支持,包括:PostgreSQL、MySQL、SQLite、Oracle。
Django 为这些数据库提供了统一的调用API。 我们可以根据自己业务需求选择不同的数据库。

目录结构如下:

HelloWorld
|-- HelloWorld
|   |-- __init__.py
|   |-- settings.py
|   |-- urls.py
|   `-- testdb.py
|   ...
|-- manage.py
|-- TestModel
|   |-- __init__.py
|   |-- admin.py
|   |-- models.py
|   |-- tests.py
|   |-- views.py
...

安装 mysql 驱动,可以执行以下命令安装(二个选择其中一个就可以了):

# mysql 驱动
pip install mysqlclient
# mysql 驱动
pip3 install pymysql

在这里插入图片描述
在这里插入图片描述

创建 MySQL 数据库( ORM 无法操作到数据库级别,只能操作到数据表)语法:

create database 数据库名称 default charset=utf8; # 防止编码问题,指定为 utf8

例如我们创建一个名为 runoob 数据库,编码指定为 utf8:

create database runoob default charset=utf8;   

我们在项目的 settings.py 文件中找到 DATABASES 配置项,将其信息修改为:
HelloWorld/HelloWorld/settings.py: 文件代码:

DATABASES = { 
    'default': 
    { 
        'ENGINE': 'django.db.backends.mysql',    # 数据库引擎
        'NAME': 'runoob', # 数据库名称
        'HOST': '127.0.0.1', # 数据库地址,本机 ip 地址 127.0.0.1 
        'PORT': 3306, # 端口 
        'USER': 'root',  # 数据库用户名
        'PASSWORD': '123456', # 数据库密码
    }  
}

在这里插入图片描述

如果你使用了 Python2.x 版本这里添加了中文注释,所以你需要在 HelloWorld/settings.py 文件头部添加 # -*- coding: UTF-8 -*-

上面包含数据库名称和用户的信息,它们与 MySQL 中对应数据库和用户的设置相同。Django 根据这一设置,与 MySQL 中相应的数据库和用户连接起来。

接下来,告诉 Django 使用 pymysql 模块连接 mysql 数据库:

实例# 在与 settings.py 同级目录下的 init.py 中引入模块和进行配置

import pymysql
pymysql.install_as_MySQLdb()

在这里插入图片描述

我们修改 TestModel/models.py 文件,代码如下:

HelloWorld/TestModel/models.py: 文件代码:

# models.py
from django.db import models
 
class Test(models.Model):
    name = models.CharField(max_length=20)

以上的类名代表了数据库表名,且继承了models.Model,类里面的字段代表数据表中的字段(name),数据类型则由CharField(相当于varchar)、DateField(相当于datetime), max_length 参数限定长度。
接下来在 settings.py 中找到INSTALLED_APPS这一项,如下:

HelloWorld.settings.py

# Application definition
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'TestModel.apps.TestmodelConfig'# 添加此项
]

在命令行中运行:

$ python3 manage.py migrate   # 创建表结构
$ python3 manage.py makemigrations TestModel  # 让 Django 知道我们在我们的模型有一些变更
$ python3 manage.py migrate TestModel   # 创建表结构

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

看到几行 “Creating table…” 的字样,你的数据表就创建好了。

Creating tables ...
……
Creating table TestModel_test  #我们自定义的表
……

表名组成结构为:应用名_类名(如:TestModel_test)。

在这里插入图片描述

注意:尽管我们没有在 models 给表设置主键,但是 Django 会自动添加一个 id 作为主键。

数据库操作

接下来我们在 HelloWorld 目录中添加 testdb.py 文件(下面介绍),并修改 urls.py:

HelloWorld/HelloWorld/urls.py: 文件代码:

from django.urls import path
from . import views,testdb
 
urlpatterns = [
    path('runoob/', views.runoob),
    path('testdbadd/', testdb.testdbadd),
    path('testdbget/', testdb.testdbget),
    path('testdbupdate/', testdb.testdbupdate),
    path('testdbdelete/', testdb.testdbdelete),
]
添加数据

添加数据需要先创建对象,然后再执行 save 函数,相当于SQL中的INSERT:

HelloWorld/HelloWorld/testdb.py: 文件代码:

# -*- coding: utf-8 -*-
from django.http import HttpResponse
from TestModel.models import Test

# 数据库操作 - 添加数据
def testdbadd(request):
    test1 = Test(name='runoob')
    test1.save()
    return HttpResponse("<p>数据添加成功!</p>")
    

访问 http://127.0.0.1:8000/testdb 就可以看到数据添加成功的提示。
输出结果如下:

在这里插入图片描述
在这里插入图片描述

获取数据

Django提供了多种方式来获取数据库的内容,如下代码所示:

HelloWorld/HelloWorld/testdb.py: 文件代码:

# -*- coding: utf-8 -*-
from django.http import HttpResponse
from TestModel.models import Test
 
# 数据库操作 - 获取数据
def testdbget(request):
    # 初始化
    response = ""
    response1 = ""
    
    
    # 通过objects这个模型管理器的all()获得所有数据行,相当于SQL中的SELECT * FROM
    listTest = Test.objects.all()
        
    # filter相当于SQL中的WHERE,可设置条件过滤结果
    response2 = Test.objects.filter(id=1) 
    
    # 获取单个对象
    response3 = Test.objects.get(id=1) 
    
    # 限制返回的数据 相当于 SQL 中的 OFFSET 0 LIMIT 2;
    Test.objects.order_by('name')[0:2]
    
    #数据排序
    Test.objects.order_by("id")
    
    # 上面的方法可以连锁使用
    Test.objects.filter(name="runoob").order_by("id")
    
    # 输出所有数据
    for var in listTest:
        response1 += var.name + " "
    response = response1
    return HttpResponse("<p>" + response + "</p>")
    

在这里插入图片描述

更新数据

修改数据可以使用 save() 或 update():
HelloWorld/HelloWorld/testdb.py: 文件代码:

# -*- coding: utf-8 -*-
from django.http import HttpResponse
from TestModel.models import Test
 
# 数据库操作 - 更新数据
def testdbupdate(request):
    # 修改其中一个id=1的name字段,再save,相当于SQL中的UPDATE
    test1 = Test.objects.get(id=1)
    test1.name = 'Google'
    test1.save()
    
    # 另外一种方式
    #Test.objects.filter(id=1).update(name='Google')
    
    # 修改所有的列
    # Test.objects.all().update(name='Google')
    
    return HttpResponse("<p>修改成功</p>")
    

在这里插入图片描述
在这里插入图片描述

删除数据

删除数据库中的对象只需调用该对象的delete()方法即可:
HelloWorld/HelloWorld/testdb.py: 文件代码:

# -*- coding: utf-8 -*-
from django.http import HttpResponse
from TestModel.models import Test
 
# 数据库操作 - 删除数据
def testdbdelete(request):
    # 删除id=1的数据
    test1 = Test.objects.get(id=1)
    test1.delete()
    
    # 另外一种方式
    # Test.objects.filter(id=1).delete()
    
    # 删除所有数据
    # Test.objects.all().delete()
    
    return HttpResponse("<p>删除成功</p>")

在这里插入图片描述
在这里插入图片描述

八、Django 表单

HTML表单是网站交互性的经典方式。 本章将介绍如何用Django对用户提交的表单数据进行处理。

HTTP 请求

  • HTTP协议以"请求-回复"的方式工作。客户发送请求时,可以在请求中附加数据。服务器通过解析请求,就可以获得客户传来的数据,并根据URL来提供特定的服务。

GET 方法

  • 我们在之前的项目中创建一个 search.py 文件,用于接收用户的请求:

/HelloWorld/HelloWorld/search.py 文件代码:

from django.http import HttpResponse
from django.shortcuts import render
# 表单
def search_form(request):
    return render(request, 'search_form.html')
 
# 接收请求数据
def search(request):  
    request.encoding='utf-8'
    if 'q' in request.GET and request.GET['q']:
        message = '你搜索的内容为: ' + request.GET['q']
    else:
        message = '你提交了空表单'
    return HttpResponse(message)

在模板目录 templates 中添加 search_form.html 表单:

/HelloWorld/templates/search_form.html 文件代码:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Django教程(runoob.com)</title>
</head>
<body>
    <form action="/search/" method="get">
        <input type="text" name="q">
        <input type="submit" value="搜索">
    </form>
</body>
</html>

urls.py 规则修改为如下形式:

/HelloWorld/HelloWorld/urls.py 文件代码:

from django.urls import path , include , re_path
from . import views ,testdb,search
 
urlpatterns = [
    re_path(r'^search-form/$', search.search_form),
    re_path(r'^search/$', search.search),
]

访问地址 http://127.0.0.1:8000/search-form/ 并搜索,结果如下所示:

在这里插入图片描述

POST 方法

上面我们使用了 GET 方法,视图显示和请求处理分成两个函数处理。
提交数据时更常用 POST 方法。我们下面使用该方法,并用一个URL和处理函数,同时显示视图和处理请求。
我们在 templates 创建 post.html:

/HelloWorld/templates/post.html 文件代码:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Django教程(runoob.com)</title>
</head>
<body>
    <form action="/search-post/" method="post">
        {% csrf_token %}
        <input type="text" name="q">
        <input type="submit" value="搜索">
    </form>
 
    <p>{{ rlt }}</p>
</body>
</html>

在模板的末尾,我们增加一个 rlt 记号,为表格处理结果预留位置。
表格后面还有一个 {% csrf_token %} 的标签。csrf 全称是 Cross Site Request Forgery。这是 Django 提供的防止伪装提交请求的功能。POST 方法提交的表格,必须有此标签。
在HelloWorld目录下新建 search2.py 文件并使用 search_post 函数来处理 POST 请求:

/HelloWorld/HelloWorld/search2.py 文件代码:

# -*- coding: utf-8 -*-
from django.shortcuts import render
from django.views.decorators import csrf
 
# 接收POST请求数据
def search_post(request):
    ctx ={}
    if request.POST:
        ctx['rlt'] = request.POST['q']
    return render(request, "post.html", ctx)

urls.py 规则修改为如下形式:

/HelloWorld/HelloWorld/urls.py 文件代码:

from django.urls import path , include,re_path
from . import views ,testdb,search,search2
 
urlpatterns = [
    re_path(r'^search-form/$', search.search_form),
    re_path(r'^search/$', search.search),
    re_path(r'^search-post/$', search2.search),    
]

访问 http://127.0.0.1:8000/search-post/ 显示结果如下:

在这里插入图片描述
在这里插入图片描述

完成以上实例后,我们的目录结构为:

HelloWorld
|-- HelloWorld
|   |-- __init__.py
|   |-- __init__.pyc
|   |-- search.py
|   |-- search.pyc
|   |-- search2.py
|   |-- search2.pyc
|   |-- settings.py
|   |-- settings.pyc
|   |-- testdb.py
|   |-- testdb.pyc
|   |-- urls.py
|   |-- urls.pyc
|   |-- views.py
|   |-- views.pyc
|   |-- wsgi.py
|   `-- wsgi.pyc
|-- TestModel
|   |-- __init__.py
|   |-- __init__.pyc
|   |-- admin.py
|   |-- admin.pyc
|   |-- apps.py
|   |-- migrations
|   |   |-- 0001_initial.py
|   |   |-- 0001_initial.pyc
|   |   |-- __init__.py
|   |   `-- __init__.pyc
|   |-- models.py
|   |-- models.pyc
|   |-- tests.py
|   `-- views.py
|-- db.sqlite3
|-- manage.py
`-- templates
    |-- base.html
    |-- hello.html
    |-- post.html
    `-- search_form.html

注意:
错误信息 ImportError: cannot import name 'url' from 'django.conf.urls' 表示您尝试从 django.conf.urls 模块中导入一个不存在的 url。在 Django 1.10 之前,url() 函数确实存在于 django.conf.urls 模块中,但在 Django 1.10 及以后的版本中,它被移到了 django.urls 模块。

为了解决这个问题,您应该从 django.urls 模块导入 path 和/或 re_path(如果您需要正则表达式来匹配 URL),而不是 url。以下是如何正确导入和使用它们的示例:

# 在 Django 2.0 及以上版本中
from django.urls import path

urlpatterns = [
    path('test/', test_view, name='test'),
]

# 如果您需要使用正则表达式来匹配 URL
from django.urls import re_path

urlpatterns = [
    re_path(r'^test/$', test_view, name='test'),
]

如果您的项目使用的是 Django 1.11 或更早的版本,并且您希望继续使用 url() 函数,您应该这样导入:

# 在 Django 1.11 或更早的版本中
from django.conf.urls import url

urlpatterns = [
    url(r'^test/$', test_view, name='test'),
]

请根据您的 Django 版本选择正确的导入方式,并更新您的 URL 配置。如果您正在使用较新版本的 Django,请确保使用 path 或 re_path。如果您正在使用较旧版本的 Django,并且确实需要使用 url(),确保从正确的位置导入。

九、Django ECharts

1. 安装 ECharts

您可以通过 CDN 直接在模板中引用 ECharts,或者将其下载到您的项目中。
通过 CDN 引用
在模板的 部分添加 ECharts 的 CDN 链接:

<script src="https://cdn.jsdelivr.net/npm/echarts/dist/echarts.min.js"></script>

2. 创建 Django 视图

在您的 Django 视图中,准备要传递给模板的数据。
charts.py

from django.shortcuts import render

def echarts_pie_chart_view(request):
    data = {
        '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})

3. 创建 Django 模板

在您的 Django 模板中,添加一个用于放置 ECharts 饼图的

元素,并使用 ECharts 初始化饼图。
echarts_pie_chart.html

<!DOCTYPE html>
<html>
<head>
    <title>ECharts 饼图</title>
    <!-- 引入 ECharts -->
    <script src="https://cdn.jsdelivr.net/npm/echarts/dist/echarts.min.js"></script>
</head>
<body>

<!-- ECharts 饼图容器 -->
<div id="echartsPieChart" style="width: 600px;height:400px;"></div>

<script>
// 获取 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} <br/>{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);
</script>

</body>
</html>

这里也可以将Data 改为动态{% for item in pie_data %} 加载

<!DOCTYPE html>
<html>
<head>
    <title>ECharts 饼图</title>
    <!-- 引入 ECharts -->
    <script src="https://cdn.jsdelivr.net/npm/echarts/dist/echarts.min.js"></script>
</head>
<body>

<!-- ECharts 饼图容器 -->
<div id="echartsPieChart" style="width: 600px;height:400px;"></div>

<script>
// 获取 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} <br/>{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);
</script>

</body>
</html>

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 文件。

<!-- templates/upload_excel.html -->
<form method="post" action="{% url 'import_excel' %}" enctype="multipart/form-data">
    {% csrf_token %}
    <input type="file" name="file" accept=".xlsx, .xls">
    <input type="submit" value="Upload">
</form>

<!-- ECharts 饼图容器 -->
<div id="echarts-pie" style="width: 600px;height:400px;"></div>

<!-- 引入 ECharts -->
<script src="https://cdn.jsdelivr.net/npm/echarts@5.3.2/dist/echarts.min.js"></script>

<script>
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));
};
</script>

5: 启动 Django 服务器并测试

启动 Django 服务器,并在浏览器中访问 http://127.0.0.1:8000/report/upload_excel/ , 您创建的 HTML 页面。上传一个 Excel 文件,您应该会看到 ECharts 饼图显示上传的数据。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

### 部署 Anything-LLM 的服务器配置指南 为了成功部署 Anything-LLM 模型,需遵循以下方法和工具链来实现完整的云端部署流程。以下是关于如何在 AWS 上通过 CloudFormation 和其他技术栈完成部署的详细介绍。 #### 1. 使用 AWS 进行云部署 AWS 提供了一种灵活的方式来托管大型语言模型 (LLMs),并支持自动化的基础设施管理。可以通过 CloudFormation 来定义资源模板,从而简化部署过程[^1]。CloudFormation 是一种声明式的资源配置方式,允许开发者以 YAML 或 JSON 文件的形式描述所需的服务架构。 下面是一个简单的 CloudFormation 示例文件片段用于创建 EC2 实例运行 LLMs: ```yaml Resources: Instance: Type: 'AWS::EC2::Instance' Properties: ImageId: ami-0c94855ba95b798c7 # 替换为适合的操作系统镜像ID InstanceType: t3.medium # 可根据需求调整实例大小 KeyName: my-key-pair # SSH密钥名称 SecurityGroupIds: - sg-xxxxxxxxxx # 安全组ID列表 SubnetId: subnet-yyyyyyyyyy # 子网ID ``` 此脚本会启动一台虚拟机作为基础环境,在该环境中安装必要的依赖项以及加载预训练好的模型权重数据集。 #### 2. 利用 anything-llm 开源项目 anything-llm 是由 Mintplex Labs 维护的一个开源框架,旨在帮助用户轻松构建自己的定制化 AI 应用程序[^2]。它不仅提供了丰富的 API 接口文档说明还包含了详细的示例代码便于快速上手实践操作。对于想要深入了解其内部工作机制或者寻求更高级功能扩展可能性的人来说,《大模型 llm 部署》一文中提到的内容将是很好的参考资料[^3]。 #### 3. 技术选型建议 当考虑具体的技术实施方案时可以从以下几个方面入手: - **前端界面开发**:推荐采用 Vue.js 结合 LogicFlow 创建交互性强且美观大方的应用页面; - **后端服务搭建**:基于 Python/Django 构建稳定高效的 RESTful Web Service 平台; - **自然语言处理能力增强**:引入 LangChain 工具包辅助完成复杂任务流设计如对话理解等场景应用; - **持久化存储解决方案**:选用 PostgreSQL 数据库搭配 PGVector 插件满足向量化检索的需求; - **核心算法引擎集成**:除了 Ollama 外还可以尝试接入 Azure OpenAI、Google Gemini Pro Max 等多种主流厂商提供的高性能计算单元选项[^4]; ```python from langchain import PromptTemplate, FewShotPromptTemplate from ollama import Model model = Model("meta-llama/Llama-2-70B-chat") template = """Question: {question} Answer: """ prompt = PromptTemplate(template=template, input_variables=["question"]) few_shot_prompt = FewShotPromptTemplate( examples=[{"question": "What is the capital of France?", "answer":"Paris"}], example_formatter=lambda x:f"Q:{x['question']}\nA:{x['answer']} ", suffix="\n\n{input}", prefix="The following are examples:\n", input_variables=["input"] ) response = model(few_shot_prompt.format(input="Who was Albert Einstein?")) print(response) ``` 上述样例展示了如何利用 LangChain 中的提示工程技巧并通过调用远程主机上的 Meta Llama v2 版本来获取高质量的回答结果。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

IT小郭.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值