Django是一个开源的、用于构建Web应用程序的高级Python Web框架。
安装
pip install django
创建项目
Django中项目会有一些默认的文件和默认的文件夹
在项目文件夹下运行,生成默认文件:
D:\Anaconda3\envs\DPlearning\Scripts\django-admin.exe startproject 项目名
添加到系统环境变量后可以不用输入路径。
默认文件介绍
默认生成的文件:
manager.py
:项目的管理、启动项目、创建app、数据管理【不需要修改】与项目同名的文件夹
asgi.py
: 接收网络请求(异步请求)【不需要修改】wsgi.py
: 接收网络请求(同步请求)【不需要修改 】urls.py
: URL和函数的对应关系【经常操作】settting.py
: 项目配置文件。【会操作,连接数据库等配置】
app的创建和说明
一般情况下,项目下创建一个app即可。
项目目录下运行python manage.py startapp app01
会生成app01文件夹。
├─app01
│ │ admin.py 【固定,不用动】 django默认提供的后台管理
│ │ apps.py 【固定,不用动】 app的启动类
│ │ models.py 【重要】 对数据库进行操作。不需要再用pymysql了。
│ │ tests.py 【固定,不用动】 单元测试
│ │ views.py 【重要】 函数
│ │ __init__.py
│ │
│ └─migrations 【固定,不用动】 数据库变更记录
│ __init__.py
│
└─mydjango
│ asgi.py
│ settings.py
│ urls.py
│ wsgi.py
└─ __init__.py
快速上手
- 确保app已注册:
\mydjango\settings.py
中的INSTALLED_APPS
增加'app01.apps.App01Config'
。app01
改成自己新建的app的名称 - 编写URL和视图函数对应关系
urls.py
- 编写视图函数
view.py
- 启动django项目。命令行启动:
python manage.py runserver
templates
def user_list(request):
# 去app01下的templates下的user_list.html。根据app的注册顺序去找templates下的user_list.html
return render(request,'user_list.html')
def user_add(request):
return render(request,'user_add.html')
静态文件
在开发过程中,一般将:
- 图片
- css
- js
都会当作静态文件处理。
django中,一般将静态文件放在app目录下的static中。
- 在app目录下创建
static
文件夹 - 顶部{% load static %},引入静态文件。
<link rel="stylesheet" href="{% static 'plugins/bootstrap-3.4.1/css/bootstrap.min.css' %}" />
,<script src="{% static 'js/jquery-3.7.1.min.js' %}"></script>
模板语法
本质上:在html中写一些占位符,由数据对这些占位符进行替换和处理。
当浏览器访问时,先访问utls.py
,然后跳转到views.py
函数,函数的render
方法将含模板语法的html转换为标准的html传给浏览器,最后浏览器读取标准html解析并显示。
- 单独一个值用花括号
{}
def tpl(request):
name = "韩超"
return render(request,'tpl.html',{"n1":name})
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>TPL</title>
</head>
<body>
<h1>TPL</h1>
<div>{{ n1 }}</div>
</body>
</html>
- 列表(元组)的索引
<!-- 列表的第一个索引 -->
<div>{{ n2.0 }}</div>
<!-- 列表的第二个索引 -->
<div>{{ n2.1 }}</div>
<!-- 列表的第三个索引 -->
<div>{{ n2.2 }}</div>
- 循环
{% for item in n2 %}
<span>{{item}}</span>
{% endfor %}
- 字典
<!-- 字典的获取 -->
{{ n3 }}
{{ n3.name }}
{{ n3.salary }}
{{ n3.role }}
<!-- 获取所有的键 -->
{% for item in n3.keys %}
<li>{{ item }}</li>
{% endfor %}
<!-- 获取所有的键值 -->
{% for item in n3.values %}
<li>{{ item }}</li>
{% endfor %}
<!-- 获取键值对 -->
{% for k,v in n3.items %}
<li>{{ k }} = {{ v }}</li>
{% endfor %}
- 列表里嵌套字典:[{},{},{}]
{{ n4.1.name }}
{{ n4.1.salary }}
{{ n4.1.role }}
{{ n4.2.name }}
{{ n4.2.salary }}
{{ n4.2.role }}
{% for item in n4 %}
<div>
{{ item.name }}
{{ item.salary }}
{{ item.role }}
</div>
{% endfor %}
- if语句
{% if n1 == "韩超" %}
<h1>NB</h1>
{% elif n1 == "XxX" %}
<h1>HH</h1>
{% else %}
<h1>SB</h1>
{% endif %}
案例:伪联通新闻中心
def news(request):
# 1. 获取联通新闻的数据
urls = "https://www.chinaunicom.com.cn/api/article/NewsByIndex/2/2023/12/news"
# 2. 解析数据
res = requests.get(urls,headers={"User-Agent":"Mozilla/5.0"})
data_list = res.json()
# 3. 获取数据
return render(request,'news.html',{"news_list":data_list})
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>联通新闻中心</title>
</head>
<body>
<h1>联通新闻中心</h1>
<ul>
{% for item in news_list %}
<li>{{item.news_title}} 时间: {{item.post_time}}</li>
{% endfor %}
</ul>
</body>
</html>
效果:
请求和相应
def qingqiuxiangying(req):
# request是一个对象,包含了请求的所有信息
# 1. 获取请求的方式 GET/POST
print(req.method)
# 2. 在URL上传递值:/request/?name=韩超&age=18
print(req.GET)
# 3. 在请求体中提交数据
print(req.POST)
# 4. 【响应】 HttpResponse。字符串和内容返回给请求者
# return HttpResponse('请求和响应')
# 5. 【响应】 render。渲染模板文件,返回给请求者
# return render(req,'request.html')
# 6. 【响应】 redirect。重定向,返回给请求者。
return redirect('https://www.baidu.com')
案例:用户登录
Django默认要求在处理POST请求时包含CSRF令牌。确保您的表单包含{% csrf_token %}标签
def login(request):
# 如果是get请求,返回登录页面
if request.method == "GET":
return render(request,'login.html')
else:
# 如果是post请求
# print(request.POST)
username = request.POST.get('user')
password = request.POST.get('pwd')
if username == 'admin' and password == '123':
# 登录成功
return redirect("https://www.chinaunicom.com.cn")
else:
# 登录失败
error_msg = '用户名或密码错误'
# return HttpResponse('登录失败')
return render(request,'login.html',{'error_msg':error_msg})
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>用户登录</title>
</head>
<body>
<h1>用 户 登 录</h1>
<form method="post" action="/login">
<!-- 表单验证(加在form表单里面) -->
{% csrf_token %}
<input type="text" name="user" placeholder="用户名">
<input type="password" name="pwd" placeholder="密码">
<input type="submit" value="提交" />
<span style="color: red;">{{ error_msg }}</span>
</form>
</body>
</html>
数据库操作--ORM框架
Flask中一般用pymysql操作数据库,但是django中已经提供了数据库工具--ORM框架。
- ORM对pymysql等库进行了封装,所以使用起来更简洁。
Django最新版本对pymysql支持一般,所以建议安装mysqlclient。如果安装失败就下载whl包离线安装。
pip install mysqlclient
ORM可以实现:
- 创建和修改数据库中的表(不用再写sql语句)。【无法创建数据库】
- 操作表中的数据(不用再写sql语句)
操作数据库中的表
- 创建数据库
- 启动mysql服务
- 自带工具创建数据库
- 修改django设置文件
settings.py
,将DATABASES改为mysql数据库引擎。
DATABASES = {
'default':{
'ENGINE':'django.db.backends.mysql', # 数据库引擎
'NAME': 'xxx', # 数据库名
'USER': 'xxx', # 用户名
'PASSWORD': 'xxxx', # 密码
'HOST':'127.0.0.1', # 主机
'PORT': '3306', # 端口
}
}
- 使用django操作数据库中的表
- 创建表
- 删除表
- 修改表
打开models.py
文件,写入以下内容:
from django.db import models
# Create your models here.
class UserInfo(models.Model):
'''
create table app01_userinfo(
id bigint primary key auto_increment,
name varchar(32),
password varchar(64),
age int
)
'''
# 上述sql语句的python代码实现
name = models.CharField(max_length=32)
password = models.CharField(max_length=64)
age = models.IntegerField()
必须确保已经注册app
然后执行命令:
python manage.py makemigrations
python manage.py migrate
sql命令查看数据库中创建的表
mysql> show tables;
+----------------------------+
| Tables_in_unicom |
+----------------------------+
| app01_userinfo |
| auth_group |
| auth_group_permissions |
| auth_permission |
| auth_user |
| auth_user_groups |
| auth_user_user_permissions |
| django_admin_log |
| django_content_type |
| django_migrations |
| django_session |
+----------------------------+
11 rows in set (0.00 sec)
能看到创建了11个表。其中后面十个是默认生成的表(按照setting.py
中的INSTALL_APPS
的设置自动创建的。后期不需要可以删除)
如果想删除某个表,可以删除models.py
中的特定的类,然后重新执行:
python manage.py makemigrations
python manage.py migrate
如果想增加表,就在models.py
中新建类,再执行命令。
如果想在表中新增列,那么就在对应的class里新增创建列的代码。然后重新运行命令。终端中会提示两个选择:1 or 2。
其中:1代表。提供一次性默认值列中每个值都用你提供的默认值(将在该列具有空值的所有现有行上设置)。2代表退出并在 models.py 中手动定义默认值。
- 手动输入一个值
- 设置默认值:
age = models.IntegerField(default=2)
- 允许为空:
data = models.IntegerField(null=True, blank=True)
以后在开发中如果想要对表结构进行调整:
- 在
models.py
文件中操作类即可- 两条命令更新表结构
python manage.py makemigrations python manage.py migrate
操作表中的数据
- 增加数据
UserInfo.objects.create(name='alex', password='123', age=18)
- 删除数据
UserInfo.objects.filter(name='alex').delete()
UserInfo.objects.all().delete() # 删除所有数据
- 获取数据
data_list = UserInfo.objects.all() # 获取所有数据,得到一个列表[对象1,对象2,对象3...]
for obj in data_list:
print(obj.name,obj.password,obj.age) # 获取每一行的数据
# 获取单条数据
UserInfo.objects.filter(id=1) # 得到数据[对象1,]
data = UserInfo.objects.filter(id=1).first() # 获取id=1的数据,得到一行数据[对象]
print(data.name,data.password,data.age)
- 更新数据
UserInfo.objects.filter(name='alex').update(age=19)
UserInfo.objects.all().update(age=19)
案例:用户管理
- 展示用户列表
- url
函数
- 获取所有用户信息
- HTML渲染
from app01.models import UserInfo
def info_list(request):
# 获取所有数据
data_list = UserInfo.objects.all()
for obj in data_list:
print(obj.name,obj.password,obj.age)
return render(request,'info_list.html',{'data_list':data_list})
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>用户列表</title>
<link rel="stylesheet" href="{% static 'plugins/bootstrap-3.4.1/css/bootstrap.min.css' %}">
</head>
<body>
<h1 class="page-header">Info列表</h1>
<table class="table table-hover">
<thead>
<tr>
<th>ID</th>
<th>姓名</th>
<th>密码</th>
<th>年龄</th>
</tr>
</thead>
<tbody>
{% for obj in data_list %}
<tr>
<td>{{ obj.id }}</td>
<td>{{ obj.name }}</td>
<td>{{ obj.password }}</td>
<td>{{ obj.age }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</body>
</html>
- 添加用户
- url
函数
- GET
- POST
from app01.models import UserInfo
def info_add(req):
if req.method == "GET":
return render(req,'info_add.html')
username = req.POST.get('user')
password = req.POST.get('pwd')
age = req.POST.get('age')
UserInfo.objects.create(name=username,password=password,age=age)
return redirect('/info/list')
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<h1>增加用户</h1>
<form method="post">
{% csrf_token %}
<input type="text" name="user" placeholder="用户名">
<input type="text" name="pwd" placeholder="密码">
<input type="text" name="age" placeholder="年龄">
<input type="submit" value="提 交">
</form>
</body>
</html>
- 删除用户
def delete(req):
# 获取要删除的id
nid = req.GET.get('nid')
# 根据id删除数据
UserInfo.objects.filter(id=nid).delete()
return HttpResponse('删除成功')