一、django
python解释器目录结构
c:\python39
-python.exe
-Scripts
-pip.exe
-django-admin.exe 创建django项目目录的工具(脚手架)
-Lib
-内置模块
-site-package
-openpyxl
-python-dox
-flask
-django 源码
创建项目
在相要创建的位置打开cmd(打开到目录位置,在文件目录搜索栏输入cmd),在python安装django且已经将script加入到环境变量当中时,直接输入
django-admin startproject 项目名称
即可创建django项目
也可以在pycharm专业版直接新建django项目,和在命令行中正统的创建方法不同,这种方法会多添加两个东西
- 1读一个templates文件夹
- 2在settings.py中多了一些东西(意思是在最外层的templates中寻找插件),如下图,暂时不需要也删掉
左边为pycharm创建的项目,在settings里面添加了多余的暂时不需要的东西
默认文件介绍
manage.py项目的管理,启动项目,创建app,数据管理 默认放置
asgi 接受网络请求 默认放置 同步
wsgi 接受网络请求 默认放置 异步
urls url和函数的对应关系 尝尝操作
settings 项目配置文件:连接数据库 尝尝操作
3创建app
- 创建app
python manage.py startapp app01
- app是比项目小的聚集
-项目
-app用户管理(app里独立的表结构 函数 html模版 css)
-app订单管理
-后台管理
-app网站
-appAPI
文件目录
manage.py
|
|
+---app01
| | admin.py 固定
| | apps.py 固定 app启动类
| | models.py 重要
| | tests.py 单元测试 固定
| | views.py 重要 定义函数
| | __init__.py
| |
| \---migrations 数据库字段变更
| __init__.py
|
+---djangoProject1
| | asgi.py
| | settings.py
| | urls.py
| | wsgi.py
| | __init__.py
4快速上手
- 1注册app
-
2编写url和视图函数对应关系
-
3编写视图函数
启动项目
1通过命令行
python manage.py runserver 127.0.0.1:8000
2pycharm启动
templates模版
1如果配置了settings.py中的templates里的dir,先在根目录中找(一般加配置加的都是这个位置),找不到转2
2然后再依据app的注册顺序在每个app里寻找
from django.shortcuts import render,HttpResponse
# Create your views here.
def index(request):
return HttpResponse("欢迎使用")
def user_list(request):
#1如果配置了settings.py中的templates里的dir,先在根目录中找(一般加配置加的都是这个位置),找不到转2
#2然后再依据app的注册顺序在每个app里寻找
return render(request, "user_list.html")
def user_add(request):
return HttpResponse("用户添加")
静态文件
static文件放置app01文件下面
注意这里导入静态文件使用的方式和之前不同!!
{% load static %}类似于占位符django提供的模板语言
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" href="{% static 'plugins/bootstrap-3.4.1-dist/css/bootstrap.css' %}">
</head>
<body>
<h1>user_lsit</h1>
<input type="text" class="btn btn-primary" value="新建">
<img src="{% static 'img/1.jpeg' %}" alt="">
<script src="{% static 'js/jquery-3.7.1.min.js' %}"></script>
<script src="{% static 'plugins/bootstrap-3.4.1-dist/js/bootstrap.js' %}"></script>
</body>
</html>
5模板语法
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>abc</h1>
<div>
<span>{{ n1 }}</span>
<span>{{ n2 }}</span>
<span>{{ n2.0 }}</span>
<span>{{ n2.1 }}</span>
<span>{{ n2.2 }}</span>
</div>
<hr/>
<ul>
{% for item in n3 %}
<li>
{{ item.name }}
</li>
{% endfor %}
</ul>
<ul>
{% for k,v in n4.items %}
<li>
{{ k }}={{ v }}
</li>
{% endfor %}
</ul>
<hr/>
{% if n1 == "12333" %}
<div>n1</div>
{% else %}
<div>no n1</div> <!--也支持elif-->
{% endif %}
</body>
</html>
这里占位符是{% %}而里面的数据是用{{}}包裹的
view文件
def test(request):
text1="12333"
roles=["管理员","ceo","保安"]
dic={"name": "why", "salary": 100, "emial": "111sidjo"}
dics=[{"name":"why","salary":100,"emial":"111sidjo"},
{"name": "why2", "salary": 100, "emial": "111sidjo"},
{"name": "why3", "salary": 100, "emial": "111sidjo"},
]
return render(request,"test.html",{"n1":text1,"n2":roles,"n3":dics,"n4":dic})#注意单独一个值有花括号
注意这里传值是通过一个字典
这里的模版语法是dj的语法,实际上返回给浏览器的一定是将模版中占位符替换后的html文件
6请求和响应
def something(request):
# 请求
print(request.method)
print(request.GET)
print(request.POST)
# 响应
# return HttpResponse("asdd")
# return render(request,"something.html",{"title":"aaaa"})
# 重定向到其他页面
return redirect("https://baidu.com")
问:重定向是1和2这两种中的那种?
答案是2
案例 用户登陆
这里的代码可以实现对密码正确的一个简单判定,第一次请求是get请求,返回表单页面其中的占位符error_msg在第一次访问时没有被赋值,所以不会显示。当密码错误时,会传递这个变量的值,告诉用户密码错误,而在密码正确时,重定向至别的地方。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>用户登陆</h1>
<form action="/login/" method="post">
{% csrf_token %}这行代码必须有,这是dj自带的用户post的验证要在Django中使用表单,特别是在使用POST
方法提交表单时,务必包含{% csrf_token %}标签,以确保应用程序受到适当的CSRF保护。
<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>
def login(request):
if request.method == 'GET':
return render(request, "login.html")
else:
# print(request.POST)
username = request.POST.get("user")
password = request.POST.get("pwd")
print(username,password)
if username == '123' and password == '123':
return redirect("https://www.bilibili.com/")
else:
return render(request,"login.html",{"error_msg":"密码错误"})
7数据库操作
pymysql过于繁琐,orm比较简单
- 安装mysqlclient
orm
orm可以帮助我们做两件事:
1创建、修改‘删除数据库中的表(不用自己写) 但是不能创建数据库
2操作表中的数据(不用谢sql语句)
1自己创建数据库
连接
DATABASES = {
'default': {
# 说明你要连的库为mysql
'ENGINE': 'django.db.backends.mysql',
# 数据库名称
'NAME': 'gx_day15',
# IP 本地为127.0.0.1
'HOST':'127.0.0.1',
# 端口默认是3306 oracel默认端口1521
'PORT':'3306',
# 数据库用户
'USER':'root',
# 数据库密码
'PASSWORD':'123456'
}
}
###dj操作表
- 创建表
在app下的models.py里创建表
from django.db import models
# Create your models here.
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_increament primary key,
name varchar(32),
password varchar(64),
age int
"""
之后需要执行下面两行命令才会创建表
python manage.py makemigrations
python manage.py migrate
要做这个事情,有个大前提,app已经注册在settings里
- 删除表
- 修改表
只需要更该models.py中定义的class再迁移就修改或者删除表了
有一点需要强调,如过在已经定义的表中要新加一列有两种解决办法,要么设置默认值,要么为空
class UserInfo(models.Model):
name=models.CharField(max_length=32)
password=models.CharField(max_length=64)
age=models.IntegerField()
data=models.CharField(max_length=16)这行是选择1设置的值
text=models.CharField(max_length=16,default="333")默认值
mobile = models.CharField(max_length=16,blank=True,null=True)可以为空
orm操作表
内容都在代码里面了,创建删除筛选修改
注意导入models的时候,前面要加上app的名字如 from app01.models import Department,UserInfo
def orm(requset):
#1新建表,首先先从models中引入定义表的类
# Department.objects.create(title="销售部")
# Department.objects.create(title="IT部")
# Department.objects.create(title="运营部")
# UserInfo.objects.create(name="王泓一",password="666",age=18)
# UserInfo.objects.create(name="王泓一2",password="6662",age=19)
#2.删除
# UserInfo.objects.filter(id=2).delete()
# UserInfo.objects.all().delete()
# 3.筛选/获取数据
#3.1all
# data_list=Department.objects.all()
# print(data_list) 输出对应表的对象
# for obj in data_list:
# print(obj.title)
#3.2filter
# data_list=Department.objects.filter(id=1)
# print(data_list) #即使是只有一条数据,也是一个列表
# print(data_list.first().title)
#4.更新数据
# Department.objects.all().update(title="**部门")
Department.objects.filter(id=1).update(title="IT部门")
Department.objects.filter(title="**部门").update(title="##部门")
return HttpResponse("成功")
案例:用户管理
1展示用户列表
- views文件
def info_list(request):
#1获取数据库中的用户信息
data_list=UserInfo.objects.all()
#2渲染,返回给用户
return render(request,"info_list.html",{"data_list":data_list})
- html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>用户数据</h1>
<table>
<thead>
<tr>
<th>id</th>
<th>姓名</th>
<th>密码</th>
<th>age</th>
</tr>
</thead>
<tbody>
{% for obj in data_list %}
<tr>
<td>
{{ obj.id }}
{{ obj.name }}
{{ obj.password }}
{{ obj.age }}
</td>
</tr>
{% endfor %}
</tbody>
</table>
</body>
</html>
2添加用户
views函数
def info_add(request):
if request.method=='GET':
return render(request, "info_add.html")
else:
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")
html文件记得加{% csrf_token %},否则post方法会出错
<!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删除用户
删除没有写html文件,而是修改了info_list.html
def info_delete(request):
nid=request.GET.get("nid")
UserInfo.objects.filter(id=nid).delete()
return redirect("/info/list")
<table class="table">
<caption>Optional table caption.</caption>
<thead>
<tr>
<th>id</th>
<th>姓名</th>
<th>密码</th>
<th>age</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>
table中新加了一列,当点击删除的时候,会跳转到一个get请求,通过占位符返还了该行数据对应的id,从而可以在/delete页面进行删除,删除完成之后会重定向到list页面。