1. 创建项目
1.1 在终端
-
进入项目目录
cd D:\study\Django\project\B_study>
-
执行命令创建项目
PS D:\study\Django\project\B_study> django-admin startproject mysite
1.2 Pycharm
但是需要专业版,我是社区版。就使用命令执行就好了
特殊说明:
- 命令行,创建的项目是标准的
- pycharm,在标准的基础上默认添加了template目录,以及setting中DIRS会添加模板路径
默认项目介绍
manage.py: 项目的管理、启动项目、创建app、数据管理、常用
urls.py: URL和函数的对应关系,常常修改
settings.py: 项目配置,常常修改
asgi.py wsgi.py: 接收网络请求
2. 创建app
- 项目
- app,用户管理 【表结构、函数、HTML模板、CSS】
- app,订单管理
。。。
注意:我们开发比较简洁,用不到多app。一般只要一个即可
PS D:\study\Django\project\B_study\mysite> python manage.py startapp app01
app01
admin.py 固定,不用动,django默认提供了admin后台管理
apps.py: 固定,不用动,app启动类
migrations: 固定,不用动,数据库变更记录
tests.py 固定,不用动,单元测试
views.py 重要,函数
models.py 重要,对数据操作
3. 上手
- 确保app已注册 【settings.py】
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'app01.apps.App01Config',
]
- 编写URL和视图函数对应关系 【urls.py】
- 编写视图函数 【views.py】
-
启动django项目
- 命令行启动
python manage.py runserver
3.1 再写一个页面
url -> 函数
函数
3.2 templates模板
如果settings.py中没有写
'DIRS': [os.path.join(BASE_DIR,'templates')]
根目录中的templates是没用的。
3.3 静态文件
在开发过程中一般将:
- 图片
- CSS
- js
都会当作静态文件处理。
3.3.1 static目录
- 在app01目录下创建static文件夹
将https://code.jquery.com/jquery-3.6.0.min.js
内容全部复制下来然后再js目录下创建jquery-3.6.0.min.js
然后在https://v3.bootcss.com/getting-started/#download
下载bootstrap-3.4.1-dist后复制到plugins目录
3.3.2 引用静态文件
4. 模板语法
本质上:在HTML中写一些占位符,有数据对这些占位符进行替换和处理。
- 单独显示一个值
- 获取列表元素
-
循环获取列表元素
<div> {% for item in n2 %} <span>{{ item }}</span> {% endfor %} </div>
- 获取字典元素
- 循环获取字典的键
<ul>
{% for item in n3.keys %}
<li>{{ item }}</li>
{% endfor %}
</ul>
<ul> #获取所有的键值
{% for k,v in n3.items %}
<li>{{ k }} = {{v}}</li>
{% endfor %}
</ul>
- 列表套字典
- 循环列表套字典
{% for item in n4%}
<div>{{ item.name }}</div>
{% endfor %}
- 条件判断语句
{% if n1 == "张三" %}
<h1>good</h1>
{% else %}
<h1>no</h1>
{% endif %}
{% if n1 == "张三" %} #elif也支持
<h1>good</h1>
{% elif %}
<h1>no</h1>
{% endif %}
注:
视图函数的render内部
- 读取含有模板语法的HTML文件
- 内部进行渲染(模板语法执行并替换数据)最终得到,只包含HTML标签的字符串。
- 将渲染(替换)完成的字符串返还给用户浏览器。
案例:伪联通新闻中心
没爬成功
from django.shortcuts import render, HttpResponse
# Create your views here.
def index(request):
return HttpResponse("欢迎使用")
def user_list(request):
# 1. 优先去项目根目录的templates中寻找
# 2. 根据app的注册顺序,逐一去他们的templates目录中寻找
return render(request, "user_list.html")
def user_add(request):
return render(request, "user_add.html")
def tpl(request):
name = "feng"
roles = ["管理员","CEO","保安"]
user_info = {"name": "张三","salary": 10000,"role": "CTO"}
data_list = [
{"name": "张三", "salary": 10000, "role": "CTO"},
{"name": "李四", "salary": 10000, "role": "CTO"},
{"name": "王二", "salary": 10000, "role": "CTO"},
]
return render(request, "tpl.html", {"n1" : name,"n2" : roles,"n3" : user_info,"n4" : data_list})
def news(request):
# 1.定义一些新闻(字典或列表) 或 数据库 网络请求去获取联通新闻
# 向地址:http://www.chinaunicom.cn/api/article/NewsByIndex/2/2023/04/new 发送请求
# 第三方模块: requests
import requests
import json
headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36"}
res = requests.get("https://www.ecut.edu.cn/7562/list.htm",headers=headers)
data_list = res.json()
print(data_list)
return render(request, 'news.html')
如果爬成功根据模板语法在news.html中添加内容即可
5. 请求和响应
from django.shortcuts import render, HttpResponse, redirect
def something(request):
# request是一个对象,封装了用户通过浏览器发送过来的所有数据
# 1.获取请求方式,GET/POST
print(request.method)
# 2.在URL上传递值 http://127.0.0.1:8000/something/?a=123
print(request.GET)
# 3. 在请求体中提交数据
print(request.POST)
# 4.【响应】 HttpResponse("返回内容"),内容字符串内容返回给请求者
# return HttpResponse("返回内容")
# 5.【响应】读取HTML的内容 + 渲染(替换) -> 字符串,返回给用户浏览器
# return render(request,'something.html',{"title":"来了"})
# 6.【响应】让浏览器重定向到其他的页面
return redirect("https://www.baidu.com")
案例:用户登录
CSRF验证
解决方法,表单中添加{% csrf_token %}
login.html:
<form action="/login/" method="post">
{% csrf_token %}
<input type="text" name="user" placeholder="用户名">
<input type="password" name="pwd" placeholder="密码">
<input type="submit" value="提交">
</form>
views.py
def login(request):
if request.method == "GET":
return render(request,"login.html")
else:
# 如果是POST请求,获取用户提交的数据
print(request.POST)
username = request.POST.get("user")
pwd = request.POST.get("pwd")
if username == "root" and pwd == "123":
# return HttpResponse("登录成功")
return redirect('http://www.ecut.edu.cn')
else:
# return HttpResponse("登录失败")
return render(request,'login.html', {"error_msg":"登录失败"})
login.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>用户登录</h1>
<form action="/login/" method="post">
{% csrf_token %}
<input type="text" name="user" placeholder="用户名">
<input type="password" name="pwd" placeholder="密码">
<input type="submit" value="提交">
<span>{{ error_msg }}</span>
</form>
</body>
</html>
6. 数据库操作
- MySql数据库 + pymysql
- Django开发操作数据库更简单,内部提供了ORM框架
6.1 安装第三方模块mysqlclient
pip3 install mysqlclient
pip install mysqlclient #安装mysqlclient https://www.lfd.uci.edu/~gohlke/pythonlibs/#mysqlcilent直接下载安装 我的安装路径D:\study\Django\project\test\venv\Scripts
pip install D:\study\Django\project\test\venv\Scripts\mysqlclient-1.4.6-cp37-cp37m-win_amd64.whl
6.2 ORM
ORM可以帮助我们做两件事:
-
创建、修改、删除数据库中的表(不用写SQL语句)。【无法创建数据库】
-
操作表中的数据(不用写SQL语句)。
1. 自己创建数据库
- 启动MySQL服务
- 自带工具创建数据库
create database B_study default charset utf8 collate utf8_general_ci;
2. Django连接数据库
在setting.py文件中进行配置和修改。
3. django操作表
- 创建表
- 删除表
- 修改表
创建表:在models.py文件中:
class Userinfo(models.Model):
name = models.CharField(max_length=32)
password = models.CharField(max_length=64)
age = models.IntegerField()
"""
create table app01_userinfo(
id bigint auto_increment primary key,
name varchar(32),
password varchar(64),
age int
)
"""
执行命令:
python3 manage.py makemigrations
python3 manage.py migrate
注意:app需要提前注册。
在表中新增列时,由于已存在列中可能已有数据,所以新增列必须要指定新增列对应的数据:
- 1,手动输入一个值
- 设置默认值
age = models.IntegerField(default=2)
- 允许为空
data = models.IntegerField(null=True,blank=True)
以后在开发中如果想要对表结构进行调整:
-
在models.py文件中操作类即可。
-
命令
python3 manage.py makemigrations python3 manage.py migrate
4. 操作表中的数据
class Department(models.Model):
title = models.CharField(max_length=16)
# ######## 新建数据 #########
# 新建数据 insert into app01_department(title) values("销售部")
# Department.objects.create(title="销售部")
# Userinfo.objects.create(name = "张三", password="123",age=19)
models.py
class Userinfo(models.Model):
name = models.CharField(max_length=32)
password = models.CharField(max_length=64)
age = models.IntegerField()
"""
create table app01_userinfo(
id bigint auto_increment primary key,
name varchar(32),
password varchar(64),
age int
)
"""
class Department(models.Model):
title = models.CharField(max_length=16)
-
新建数据
# 测试ORM操作表中的数据 # Department.objects.create(title="销售部") # Department.objects.create(title="IT部") # Department.objects.create(title="运营部") Userinfo.objects.create(name = "张三", password="123",age=19) Userinfo.objects.create(name = "李四", password="666",age=29)
-
删除数据
# 1.删除 Userinfo.objects.filter(id=2).delete() Department.objects.all().delete()
-
获取数据
# 3.获取数据 # 3.1 获取符合条件的数据 # data_list = [对象,对象,对象] QuerySet类型 # data_list = Userinfo.objects.all() # for obj in data_list: # print(obj.id, obj.name, obj.password, obj.age) # 3.2 获取第一条数据 【对象】 row_obj = Userinfo.objects.filter(id=1).first() print(row_obj.id,row_obj.name)
-
更新数据
# 4. 更新数据 # Userinfo.objects.all().update(password=999) # Userinfo.objects.filter(id=1).update(age=20) Userinfo.objects.filter(name="张三").update(age=28)
views.py
from app01.models import Department,Userinfo
def orm(request):
# 1.新建
# 测试ORM操作表中的数据
# Department.objects.create(title="销售部")
# Department.objects.create(title="IT部")
# Department.objects.create(title="运营部")
# Userinfo.objects.create(name = "张三", password="123",age=19)
# Userinfo.objects.create(name = "李四", password="666",age=29)
# 2.删除
# Userinfo.objects.filter(id=2).delete()
# Department.objects.all().delete()
# 3.获取数据
# data_list = [对象,对象,对象] QuerySet类型
# data_list = Userinfo.objects.all()
# for obj in data_list:
# print(obj.id, obj.name, obj.password, obj.age)
# row_obj = Userinfo.objects.filter(id=1).first()
# print(row_obj.id,row_obj.name)
# 4. 更新数据
# Userinfo.objects.all().update(password=999)
# Userinfo.objects.filter(id=1).update(age=20)
Userinfo.objects.filter(name="张三").update(age=28)
return HttpResponse("成功")
案例:用户管理
1. 展示用户列表
- url
- 函数
- 获取所用用户信息
- HTML渲染
urls.py
# 案例:用户管理
path('info_list/', views.info_list),
views.py
def info_list(request):
# 1.获取数据库中所用的用户信息
data_list = Userinfo.objects.all()
# 2. 渲染,返回给用户
return render(request,"info_list.html",{"data_list":data_list})
info_list.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>INFO列表</h1>
<a href="/info/add/">添加</a>
<table border="1">
<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>
2. 添加用户
- url
- 函数
- GET,看到页面,输入内容
- POST,提交 -> 写入到数据库。
urls.py
# 案例:用户管理
path('info/list/', views.info_list),
path('info/add/', views.info_add),
views.py
def info_add(request):
if request.method == "GET":
return render(request,"info_add.html")
#获取用户提交的数据
user = request.POST.get("user")
pwd = request.POST.get("pwd")
age = request.POST.get("age")
# 添加到数据库
Userinfo.objects.create(name=user,password=pwd,age=age)
#自动跳转
return redirect("/info/list/")
info_add.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>添加用户</h1>
<form action="/info/add/" method="post">
{% csrf_token %}
<input type="text" name="user" placeholder="用户名">
<input type="password" name="pwd" placeholder="密码">
<input type="text" name="age" placeholder="年龄">
<input type="submit" value="提交">
</form>
</body>
</html>
3. 删除用户
- url
- 函数
http://127.0.0.1:8000/info/delete/?nid=1
http://127.0.0.1:8000/info/delete/?nid=2
http://127.0.0.1:8000/info/delete/?nid=3
def 函数(request):
nid = reuqest.GET.get("nid")
Userinfo.objects.filter(id=nid).delete()
return HttpResponse("删除成功")
urls.py
# 案例:用户管理
path('info/list/', views.info_list),
path('info/add/', views.info_add),
path('info/delete/', views.info_delete),
views.py
def info_delete(request):
nid = request.GET.get('nid')
Userinfo.objects.filter(id=nid).delete()
return redirect("/info/list")
info_list.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>INFO列表</h1>
<a href="/info/add/">添加</a>
<table border="1">
<thead>
<tr>
<th>ID</th>
<th>姓名</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>
<td>
<a href="/info/delete/?nid={{ obj.id }}">删除</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</body>
</html>
4. 汇总
urls.py
# 案例:用户管理
path('info/list/', views.info_list),
path('info/add/', views.info_add),
path('info/delete/', views.info_delete),
views.py
def info_list(request):
# 1.获取数据库中所用的用户信息
data_list = Userinfo.objects.all()
# 2. 渲染,返回给用户
return render(request,"info_list.html",{"data_list":data_list})
def info_add(request):
if request.method == "GET":
return render(request,"info_add.html")
#获取用户提交的数据
user = request.POST.get("user")
pwd = request.POST.get("pwd")
age = request.POST.get("age")
# 添加到数据库
Userinfo.objects.create(name=user,password=pwd,age=age)
#自动跳转
return redirect("/info/list/")
def info_delete(request):
nid = request.GET.get('nid')
Userinfo.objects.filter(id=nid).delete()
return redirect("/info/list")
list_info.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>INFO列表</h1>
<a href="/info/add/">添加</a>
<table border="1">
<thead>
<tr>
<th>ID</th>
<th>姓名</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>
<td>
<a href="/info/delete/?nid={{ obj.id }}">删除</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</body>
</html>
list_add.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>添加用户</h1>
<form action="/info/add/" method="post">
{% csrf_token %}
<input type="text" name="user" placeholder="用户名">
<input type="password" name="pwd" placeholder="密码">
<input type="text" name="age" placeholder="年龄">
<input type="submit" value="提交">
</form>
</body>
</html>