一、Django 安装
pip install Django
Python 安装目录结构说明
c:\python3.9
├─python.exe
├─Scripts
│ ├─pip.exe
│ └─django‑admin.exe # 创建项目的工具
└─lib
├─内置模块
└─site‑packages
├─openpyxl
├─python‑docx
├─flask
└─django # Django框架源码
二、创建 Django 项目
2.1 命令行创建项目
-
打开终端,cd 切换到项目存放目录
-
两种执行方式
Scripts未配置系统环境变量,写完整路径
"C:\Users\86156\AppData\Local\Programs\Python\Python39\Scripts\django-admin.exe" startproject 项目名
Scripts配置环境变量后,简写
django-admin startproject 项目名称
2.2 Pycharm 创建 Django 项目
注意:
- 命令行创建的是标准原生项目
- Pycharm 创建会额外自动生成
templates目录;settings.py也会有少量附加配置,不需要可以手动删除。
默认项目目录文件说明
mysite
├─manage.py # 项目管理入口:启动项目、创建APP、数据库迁移,高频使用
└─mysite
├─__init__.py
├─settings.py # 项目全局配置,经常修改
├─urls.py # URL地址与视图函数映射关系,经常修改
├─asgi.py # 异步网络请求入口,一般不用修改
└─wsgi.py # 同步网络请求入口,一般不用修改
三、创建 APP
APP 用来拆分业务模块,例如用户管理、订单管理、后台管理、API。 小型项目,通常只创建1 个 APP即可。
终端执行(项目根目录执行)
python manage.py startapp app01
APP 目录结构
app01
├─__init__.py
├─admin.py # Django自带后台管理,一般不用修改
├─apps.py # APP启动类,固定
├─migrations # 数据库迁移变更记录
│ └─__init__.py
├─models.py # ⭐重要:数据库模型类
├─tests.py # 单元测试
└─views.py # ⭐重要:视图函数,业务逻辑
3.1 APP 注册
创建完 APP 之后,必须在settings.py中注册,否则 Django 无法识别。
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'app01', #注册自己创建的app
]
3.2 开发流程
- 在
settings.py注册 APP urls.py编写 URL 与视图函数映射views.py编写视图函数- 启动项目
3.3 启动 Django 项目
#终端命令启动
python manage.py runserver
也可以直接使用 Pycharm 快捷启动。
四、模板与静态文件
4.1 templates 模板
在 app 目录下新建templates文件夹,存放 html 页面文件。
4.2 静态文件(图片、css、js)
-
app 目录下新建
static文件夹存放静态资源 -
html 模板顶部加载静态标签
{% load static %}
4.3 模板语法
在 HTML 中书写占位符,后端传递数据对占位符进行渲染替换。
4.4 模板继承
定义母版layout.html,子页面直接继承母版,复用公共页面代码。
<!-- layout.html 母版 -->
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>{% block title %}默认标题{% endblock %}</title>
</head>
<body>
{% block content %}
<!--子页面填充内容区域-->
{% endblock %}
</body>
</html>
子页面继承写法
{% extends "layout.html" %}
{% block title %}页面标题{% endblock %}
{% block content %}
<div>子页面业务内容</div>
{% endblock %}
五、Django ORM 数据库操作
Django 内置 ORM 框架,不需要手写 SQL。
- 可以完成:创建 / 修改 / 删除表;表数据增删改查
- ⚠️ORM不能自动创建数据库,数据库需要我们手动在 MySQL 中提前建好。
5.1 安装数据库驱动
pip install mysqlclient
5.2 配置数据库连接 settings.py
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'django_db', # 手动提前创建好的数据库名
'USER': 'root', # mysql账号
'PASSWORD': '123456', # mysql密码
'HOST': '127.0.0.1',
'PORT': '3306',
}
}
5.3 models.py 编写模型类(映射数据库表)
from django.db import models
class Department(models.Model):
"""部门表"""
title = models.CharField(max_length=32,verbose_name="部门名称")
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="年龄")
account = models.DecimalField(verbose_name="账户余额",max_digits=10,decimal_places=2,default=0)
creat_time = models.DateTimeField(verbose_name="入职时间")
depart = models.ForeignKey(to="Department",to_field="id",on_delete=models.CASCADE)
gender_choices = (
(1,"男"),
(2,"女"),
)
gender = models.SmallIntegerField(verbose_name="性别",choices=gender_choices)
写完模型类之后,执行迁移命令(项目根目录终端)
python manage.py makemigrations
python manage.py migrate
新增字段注意事项: 表已有历史数据,新增列必须指定方案三选一
-
命令行手动输入默认值
-
设置字段默认值
age = models.IntegerField(default=2)
-
允许字段为空
data = models.IntegerField(null=True,blank=True)
后续修改表结构,只需要修改 models.py 模型类,再次执行两条迁移命令即可。
5.4 ORM 查询常用条件
# id等于12
models.PretttyNum.objects.filter(id=12)
# id大于12
models.PretttyNum.objects.filter(id__gt=12)
# id大于等于12
models.PretttyNum.objects.filter(id__gte=12)
# id小于12
models.PretttyNum.objects.filter(id__lt=12)
# id小于等于12
models.PretttyNum.objects.filter(id__lte=12)
#手机号以158开头
models.PretttyNum.objects.filter(mobile__startswith='158')
#手机号以9281结尾
models.PretttyNum.objects.filter(mobile__endswith='9281')
#手机号包含158
models.PretttyNum.objects.filter(mobile__contains='158')
六、分页简单示例
#切片做分页
#获取前10条
Q = models.PrettyNum.objects.all()[0:10]
#条件查询切片
Q = models.PrettyNum.objects.filter(**data_list).order_by("-level")[0:10]
#获取总条数
total = models.PrettyNum.objects.filter(**data_list).order_by("-level").count()
七、Form 组件 & ModelForm 组件
原生表单缺点:需要手动写 input、手动做数据校验、手动写错误提示。
- Form 组件:自动生成 input 标签、数据校验、错误提示;外键关联数据需要自己处理
- ModelForm 组件:基于数据模型类生成表单,开发优先选用 ModelForm
7.1 Form 简单示例
views.py
from django import forms
class MyForm(forms.Form):
user = forms.CharField(widget=forms.TextInput)
pwd = forms.CharField(widget=forms.TextInput)
email = forms.EmailField(widget=forms.TextInput)
def user_add(request):
if request.method == "GET":
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 %}
</form>
7.2 ModelForm 示例
views.py ModelForm
from django import forms
from app01.models import UserInfo
class MyForm(forms.ModelForm):
class Meta:
model = UserInfo
fields = ['name','password','age'] #指定需要渲染的字段
八、登录认证 Cookie & Session
- Cookie:浏览器存储随机字符串
- Session:服务端存储用户会话信息
8.1 视图内登录校验(原始方式)
每个视图函数开头都写判断,代码冗余。
info = request.session.get("info")
if not info:
return redirect('/login/')
8.2 中间件统一登录校验(推荐)
中间件可以对所有请求做统一拦截,不用每个视图写重复登录判断。
-
编写中间件
app01/middleware/auth.pyfrom django.utils.deprecation import MiddlewareMixin
from django.shortcuts import redirectclass AuthMiddlewareMixin(MiddlewareMixin):
def process_request(self,request):
#放行登录页面
if request.path_info == '/login/':
return
info_dict = request.session.get('info')
if info_dict:
return
#未登录跳转到登录页
return redirect('/login/') -
settings.py 注册中间件
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'app01.middleware.auth.AuthMiddlewareMixin', #自定义登录中间件
]
8.3 注销功能
def logout(request):
"""注销:清空session"""
request.session.clear()
return redirect('/login/')
九、图片验证码
安装依赖库
pip install pillow
验证码生成代码
import random
from PIL import ImageDraw,Image,ImageFont,ImageFilter
def check_code(width = 120,height = 30,char_length=5,font_file='B.ttf',font_size = 28):
code = []
img = Image.new(mode='RGB',size=(width,height),color=(255,255,255))
draw = ImageDraw.Draw(img,mode='RGB')
def rndChar():
"""生成随机大写字母"""
return chr(random.randint(65,90))
def rndColor():
"""随机颜色"""
return (random.randint(0,255),random.randint(0,255),random.randint(64,255))
font = ImageFont.truetype(font_file,font_size)
for i in range(char_length):
char = rndChar()
code.append(char)
h = random.randint(0,4)
draw.text([i * width/char_length,h],char,font=font,fill=rndColor())
#绘制干扰点
for i in range(40):
draw.point([random.randint(0,width),random.randint(0,height)], fill=rndColor())
img = img.filter(ImageFilter.EDGE_ENHANCE_MORE)
return img, ''.join(code)
if __name__ == '__main__':
img,code_str = check_code()
print(code_str)
with open('code.png','wb') as f:
img.save(f,format='png')