目录
[HttpRequest 对象](#HttpRequest 对象)
[HttpResponse 对象](#HttpResponse 对象)
[MySQL数据库 + pymysql](#MySQL数据库 + pymysql)
[Form 组件](#Form 组件)
[ModelForm 组件](#ModelForm 组件)
项目源码
本项目的完整代码已上传至 GitHub,欢迎 Star 和 Fork:
🔗 [GitHub 项目地址](https://github.com/Zhan-CF/django-user-manage.git)
如果对您有帮助,请给个 ⭐️ Star 支持一下!
相关文章
HTML+CSS+JS(https://blog.csdn.net/weixin_64555419/article/details/159431406?spm=1011.2415.3001.10575&sharefrom=mp_manage_link)
基本
django在终端创建目录的命令:
cd django项目目录(要将项目创建在哪里) #我统一放在"D:\pycharmfile\djangoProject"
django-admin startproject 项目名称
默认项目
django_test2
manage.py //项目的管理,启动项目,创建app,数据管理;不动
django_test2
__init__.py
setting.py //项目配置,动
urls.py //URL路径和函数的对应关系,动
asgi.py //接收网络请求;不动
wsgi.py //接收网络请求;不动
app
一个项目下可以有多个app,相互独立,负责不同的模块,不过一般只创一个app。
创建app,切换到主目录下,在pycharm终端输入命令:
D:\pycharmfile\mydjangoProject\django_test2> python manage.py startapp app0
创建的app下的初始项目:
app0
migrations //(固定不动)数据库变更记录
__init__.py
__init__.py
admin.py //(固定不动)django默认提供了admin后台管理功能,一般不用
apps.py //(固定不动)app启动类
models.py //(动)对数据库操作
tests.py //(固定不动)单元测试,一般不用
views.py //(动)函数一般定义在这
注册app
在seetings.py文件里的INSTALLED_APPS那里添加一行'app0.apps.App0Config',其中app0是创建的app的名字。
编写URL与函数的关系
在views.py里编写函数,在urls.py里创建关系.
编写一个基本函数:
def index(request): #request是默认参数
#request是一个对象,封装了用户通过浏览器发送过来的所有数据
return HttpResponse("欢迎") #返回一个字符串
def user_add(request):
return render(request,"user_add.html") #返回一个html页面
#在创建的app目录下创建templates目录,在里面创建html文件
启动django项目
-
pycharm命令行启动
Python manage.py runserver -
pycharm点运行按钮启动
静态资源加载
包括图片、CSS、JS等,先在app目录下创建static目录,将资源放到里面。
在html中加载此资源时,
-
先在文件开头写
{% load static %} -
若是加载CSS,在
<head>标签末尾写<link rel="stylesheet" href="{% static 'plugins/bootstrap-3.4.1/css/bootstrap.css' %}">若是加载图片,在插入地方写
<img src="{% static 'img/1.png' %}" alt="">若是引入JS,在
<body>末尾写<script src="{% static 'js/jquery-3.6.0.min.js'}"></script> <script src="{% static 'plugins/bootstrap-3.4.1/js/bootstrap.js'}"></script>
模板语法(DTL)
DTL 的语法分为四大核心块:变量、标签、过滤器、继承。
模板语法写在templates的html文件里,在views函数的render内部,会先读取含有模板语法的html文件,然后内部进行渲染(模板语法执行并替换数据),最后将渲染完成后只包含html标签的字符串返还给用户浏览器。
变量
使用双大括号来显示从 Python 视图函数(views.py)传过来的数据。
-
基本显示 :
{``{ username }} -
字典取值 :
{``{ player.hp }}(对应 Python 的player['hp']) -
对象属性/方法 :
{``{ user.get_full_name }}(调用方法不需要加括号) -
列表索引 :
{``{ skills.0 }}(对应 Python 的skills[0])
标签
标签负责逻辑判断和循环,使用百分号包裹。
A. 循环标签 (for)
常用于遍历数据库查询到的列表(如:通关副本列表)。
<ul>
{% for task in task_list %}
<li>第{{ forloop.counter }}项:{{ task.name }}</li>
{% empty %}
<li>当前暂无副本任务</li>
{% endfor %}
</ul>
提示:forloop.counter 是内置计数器,从 1 开始。
B. 条件判断 (if)
{% if user_level > 10 %}
<p class="text-danger">称号:高级玩家</p>
{% elif user_level > 5 %}
<p class="text-warning">称号:进阶玩家</p>
{% else %}
<p>称号:菜鸟</p>
{% endif %}
C. URL 解析 (url)
不要硬编码链接,使用路由别名:
<a href="{% url 'login_page' %}">点击登录</a>
请求与响应
基础结构
在 Django 的 views.py 中,每个视图函数都必须接收一个 request 对象,并且必须返回一个 response 对象。
from django.shortcuts import render, HttpResponse
def my_view(request):
# 1. 收到请求 (request)
# 2. 逻辑处理 (计算、查数据库)
# 3. 返回响应 (response)
return HttpResponse("天网系统已就绪")
HttpRequest 对象
当用户访问网页时,Django 会自动创建一个 HttpRequest 对象。常用的属性如下:
| 属性/方法 | 示例 | 作用 |
|---|---|---|
request.method |
GET 或 POST |
判断请求类型(非常重要)。 |
request.GET |
request.GET.get('id') |
获取 URL 路径里的参数(如 ?id=1)。 |
request.POST |
request.POST.get('name') |
获取表单提交的数据(如登录名)。 |
request.FILES |
request.FILES.get('avatar') |
获取上传的文件。 |
request.path |
/welcome/ |
获取当前的请求路径。 |
request.is_ajax() |
(老版本) / headers |
判断是否为异步请求。 |
HttpResponse 对象
(给用户回信)
Django 提供了几种常用的响应方式,对应不同的业务场景:
A. 返回纯文本/HTML (HttpResponse)
最基础的响应,直接返回字符串。
return HttpResponse("<h1>警告:灵魂扫描中</h1>")
B. 渲染模板 (render) ------ 最常用
将 Python 数据填入 HTML 模板并返回。
context = {'name': '萧暮雨', 'id': '001'}
return render(request, 'index.html', context)
C. 页面重定向 (redirect)
让用户跳转到另一个页面。
from django.shortcuts import redirect
return redirect('/login/') # 或者写路由别名
D. 返回 JSON 数据 (JsonResponse) ------ 前后端分离核心
如果你在写 API 接口,这个是必修课。
from django.http import JsonResponse
data = {'status': 'success', 'score': 100}
return JsonResponse(data)
注意:CSRF 防护
Django 默认非常安全。当你使用 POST 提交数据时,必须在 HTML 的 post 标签里加上:
{% csrf_token %}
如果没有这一行,Django 会出于安全考虑拒绝请求,并返回 403 Forbidden 错误。
数据库操作
MySQL数据库 + pymysql
import pymysql
# 1.连接MySQL
conn = pymysql.connect(host="127.0.0.1", port=3306, user='root', passwd="root123", charset='utf8', db='unicom')
cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)
# 2.发送指令
cursor.execute("insert into admin(username,password,mobile) values('wupeiqi','qwe123','15155555555')")
conn.commit()
# 3.关闭
cursor.close()
conn.close()
ORM
在 Django 中,操作数据库不需要写原生的 SQL 语句(如 SELECT * FROM ...),而是使用一种叫 ORM (Object-Relational Mapping) 的技术。
简单来说orm充当了一个翻译的功能,可以把我们写的Python代码翻译成对应的数据库查询语句,这样不学数据库语句也能进行数据库操作。
先安装第三方模块
pip install mysqlclient
接着去mysql创建数据库,再用django连接数据库
在settings.py文件中进行配置和修改。
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'gx_day15', # 数据库名字
'USER': 'root',
'PASSWORD': 'root123',
'HOST': '127.0.0.1', # 本机
'PORT': 3306, #端口
}
}
第一步:定义模型 (models.py)
在 Django 项目的 models.py 中定义你的数据结构。
from django.db import models
class Player(models.Model):
# 字符串字段,必须指定最大长度
name = models.CharField(max_length=32)
# 整数序列
iq = models.IntegerField(default=10)
# 自动记录创建时间
create_time = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.name
第二步:同步到数据库 (Migrations)
定义好类后,需要执行两行命令,Django 会自动帮你创建数据库表:
-
生成脚本 :
python manage.py makemigrations(检查 models.py 的变化,生成记录)。 -
执行同步 :
python manage.py migrate(真正去数据库里建表)。
第三步:增删改查 (CRUD) ------ 核心操作
这些代码通常写在 views.py 视图函数中。
A. 增 (Create)
# 方式 1
Player.objects.create(name="萧暮雨", iq=15)
# 方式 2 (实例化后保存)
p = Player(name="楚离", iq=20)
p.save()
B. 查 (Retrieve)
Django 提供了极其强大的查询接口:
| 方法 | 示例 | 作用 |
|---|---|---|
all() |
Player.objects.all() |
获取表中所有数据(返回 QuerySet 列表)。 |
filter() |
Player.objects.filter(iq=10) |
获取所有智力等于 10 的人。 |
get() |
Player.objects.get(id=1) |
获取唯一的一条数据。如果找不到或多于一条会报错。 |
exclude() |
Player.objects.exclude(name="XX") |
排除掉某个人。 |
order_by() |
Player.objects.all().order_by('-iq') |
按智力倒序排列(加减号代表倒序)。 |
想要去数据库中获取数据时:对象/字典
# 对象,当前行的所有数据。
row_object = models.Order.objects.filter(id=uid).first()
row_object.id
row_object.title
# 字典,{"id":1,"title":"xx"}
row_dict = models.Order.objects.filter(id=uid).values("id","title").first()
# queryset = [obj,obj,obj,]
queryset = models.Order.objects.all()
# queryset = [ {'id':1,'title':"xx"},{'id':2,'title':"xx"}, ]
queryset = models.Order.objects.all().values("id","title")
# queryset = [ (1,"xx"),(2,"xxx"), ]
queryset = models.Order.objects.all().values_list("id","title")
C. 改 (Update)
# 方式 1:先查再改
p = Player.objects.get(id=1)
p.iq = 99
p.save()
# 方式 2:批量修改
Player.objects.filter(name="萧暮雨").update(iq=100)
D. 删 (Delete)
# 删除单条
Player.objects.get(id=2).delete()
# 批量删除
Player.objects.filter(iq__lt=5).delete() # 删除智力小于 5 的人
模板的继承
可以定义一个包含网站公共元素(如导航栏、页脚、侧边栏)的母版,然后让其他页面只负责填充变动的部分,这样可以避免重复的cv,并且维护起来也更方便。
创建母版
在母版中,需要使用 {% block 块名 %} ... {% endblock %} 标签来"挖坑"。这些坑位将由子页面来填满。
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" href="{% static 'plugin/bootstrap-3.4.1/css/bootstrap.min.css' %}">
</head>
<body>
<nav class="navbar navbar-default">
<!--这部分原本是个完整的导航条,这里省略不写了-->
<div class="container">
{% block content %}
{% endblock %}
</div>
<script src="{% static 'js/jquery-4.0.0.min.js' %}"></script>
<script src="{% static 'plugin/bootstrap-3.4.1/js/bootstrap.min.js' %}"></script>
</body>
</html>
创建子页面
在第一行使用 {% extends '母版文件名' %} 声明继承关系。然后使用 {% block 块名 %} 来填坑。
{% extends "layout.html" %}
{% block content %}
<h2>部门管理</h2>
{% endblock %}
{``{ block.super }}:在子页面的 block 内使用,可以不覆盖母版内容,保留母版内容并追加。
Form和ModelForm组件
(对应项目的user模块)
跟着做了原始的新建用户,理了理思路,虽然做完也有点没记住。
-
原始方式是本质,但一般不会采用,太麻烦。
- 用户提交数据没有校验。 - 错误,页面上应该有错误提示。 - 页面上,没一个字段都需要我们重新写一遍。 [OK] - 关联的数据,手动去获取并展示循环展示在页面。 [OK]
- 在 Django 开发中,手动在 HTML 里写
<input>和在views.py里用request.POST.get拿数据是非常低效且容易出错的。为此,Django 提供了Form 和 ModelForm。
Form 组件
Form 组件不直接绑定数据库模型,它更像是一个独立的验证器。
主要功能:
-
自动生成 HTML :你定义字段,它帮你生成
<input>标签。 -
数据校验:检查输入是否合法(比如邮箱格式、密码长度)。
-
错误提示:如果校验失败,自动把错误信息传回前端。
代码示例
# views.py
from django import forms
class MyForm(forms.Form):
username = forms.CharField(label="用户名", min_length=3)
password = forms.CharField(label="密码", widget=forms.PasswordInput)
def user_add(request):
form = MyForm() #实例化
return render(request, 'user_add.html',{"form":form})
# user_add.html
<form method="post">
{{ form.user }}
{{ form.pwd }}
{{ form.email }}
</form>
<form method="post"> #也可以写个循环,更简单
{% for field in form%}
{{ field }}
{% endfor %}
<!-- <input type="text" placeholder="姓名" name="user" /> -->
</form>
ModelForm 组件
ModelForm 是 Form 的升级版。它可以直接绑定一个数据库模型 (Model) ,不用像Form一样再写一遍那些字段。
-
极速开发 :它会自动读取
models.py里的字段类型(比如CharField对应文本框,DateTimeField对应时间控件)。 -
一键保存 :校验通过后,直接执行
form.save()就能把数据存入数据库,连objects.create()都不用写。
代码示例
# models.py
class UserInfo(models.Model):
name = models.CharField(verbose_name="姓名", max_length=16)
password = models.CharField(verbose_name="密码", max_length=64)
age = models.IntegerField(verbose_name="年龄")
gender_choices = (
(1, "男"),
(2, "女"),
)
gender = models.SmallIntegerField(verbose_name="性别", choices=gender_choices)
# views.py
from django import forms
from app0.models import UserInfo
class MyForm(forms.ModelForm):
class Meta:
model = UserInfo
fields = ["name","password","age","xx"] #或直接写"__all__"
def user_add(request):
form = MyForm()
return render(request, 'user_add.html',{"form":form})
其他
关于一些校验

关于数据库搜索
data_dict = {"mobile":"19999999991","id":123}
models.PrettyNum.objects.filter(**data_dict) #多个条件的筛选
models.PrettyNum.objects.filter(id=12) # 等于12
models.PrettyNum.objects.filter(id__gt=12) # 大于12
models.PrettyNum.objects.filter(id__gte=12) # 大于等于12
models.PrettyNum.objects.filter(id__lt=12) # 小于12
models.PrettyNum.objects.filter(id__lte=12) # 小于等于12
models.PrettyNum.objects.filter(mobile="999") # 等于
models.PrettyNum.objects.filter(mobile__startswith="1999") # 筛选出以1999开头
models.PrettyNum.objects.filter(mobile__endswith="999") # 筛选出以999结尾
models.PrettyNum.objects.filter(mobile__contains="999") # 筛选出包含999
关于分页
略,之后用到可以回来细看
django的中间件
(对应项目的login模块)
在django中,中间件(Middleware) 是一个轻量级、底层的"插件"系统,它介入 Django 的 请求(Request) 和 响应(Response) 处理过程。实际上是个类。
中间件的工作流程
-
请求阶段 :按照
settings.py中MIDDLEWARE列表的 从上到下 顺序执行。 -
响应阶段 :按照 从下到上 的逆序执行。
中间件的五个核心方法
在一个自定义中间件类中,可以定义以下方法(最常用的是前两个):
-
process_request(self, request)-
请求刚到达 Django,还没进入 URL 路由匹配。
-
用途:登录校验、黑名单封禁。
-
返回值 :如果返回
None,继续走下一个中间件;如果返回HttpResponse,直接原路返回,不执行后面的视图。
-
-
process_view(self, request, view_func, view_args, view_kwargs)-
URL 路由匹配成功,但在执行具体的
views函数之前。 -
用途:权限控制。
-
-
process_response(self, request, response)-
视图函数执行完,返回响应给浏览器之前。
-
用途:给响应头统一加数据、记录日志。
-
-
process_exception(self, request, exception)-
当视图函数抛出异常时触发。
-
用途:收集错误日志、发送告警邮件。
-
-
process_template_response(self, request, response)- 如果视图返回的对象有
render方法(TemplateResponse),则会触发。
- 如果视图返回的对象有
中间件的定义
在app目录下创建目录middleware,在其中创建.py文件后,在其中写入类,而后在配置文件中的MIDDLEWARE列表中添加路径。


AJAX请求
(对应项目的task模块)
AJAX(Asynchronous JavaScript and XML)是一种无需刷新整个网页,与服务器交换数据并局部更新网页的技术。
传统方式(同步):
-
提交后整个页面刷新
-
用户体验差
-
需要重新加载整个页面
AJAX 方式(异步):
-
页面不刷新,局部更新
-
用户体验好
-
只传输必要的数据
项目中task模块的新建编辑删除都使用的ajax请求。
图表
(对应项目的chart模块)
使用https://echarts.apache.org/handbook/zh/get-started,cv就可以了。
文件上传
(对应项目的upload模块)
<form method="post" enctype="multipart/form-data"> <!--enctype写成这样就支持上传文件内容了,否则只能传过去文件名称-->
{% csrf_token %}
<input type="text" name="username">
<input type="file" name="avatar">
<input type="submit" value="提交">
</form>
Excel上传
<!--html-->
<form method="post" enctype="multipart/form-data" action="/depart/muti/">
{% csrf_token %}
<div class="form-group">
<input type="file" name="exc">
</div>
<input type="submit" value="上传" class="btn btn-info">
</form>
#views函数
def de_muti(request): #批量上传文件
file_obj = request.FILES.get('exc') #获取用户上传的文件对象
#print(type(file_obj))
#对象传递给openpyxl,读取文件内容
from openpyxl import load_workbook
wb= load_workbook(file_obj) #可以填文件路径,也可以填一个文件对象
#print(wb.sheetnames) #当新建一个 Excel 文件时,系统会自动创建 3 个空白工作表(sheet1,sheet2,sheet3)
sheet = wb.worksheets[0]
#循环获取每一行数据
for row in sheet.iter_rows(min_row=2): #从除表头的第一行开始
depart = row[5].value
exists = models.Department.objects.filter(title=depart).exists()
if not exists: #如果原数据库中不存在该部门,就添加
models.Department.objects.create(title=depart)
return redirect('/depart/list/')
在django的开发过程中两个特殊的文件夹:
-
static,存放静态文件的路径,包括:CSS、JS、项目图片。
-
media,用户上传的数据的目录。
在urls.py中进行配置:
from django.urls import path, re_path from django.views.static import serve from django.conf import settings urlpatterns = [ re_path(r'^media/(?P<path>.*)$', serve, {'document_root': settings.MEDIA_ROOT}, name='media'), ]在settings.py中进行配置:
import os MEDIA_ROOT = os.path.join(BASE_DIR, "media") MEDIA_URL = "/media/"