目录
Web应用
# python的就业方向
1. web方向---------->就是通过浏览器访问的应用程序--------->做网站的-------->90%的工作都是web
2. 爬虫岗位--------->就是爬取数据的
3. 数据分析方向------->工作岗位不是很多
4. AI----------->没有工作经验的先不要去----------->数学--------->AutoGPT----->python写的
5. ...
# 机遇与挑战并行
# web方向
'''通过浏览器访问的应用程序!!!'''
1. 两种模式C/S、B/S
B/S:browser---------------->server
2. Web应用程序的优点
2.1 只需要有一个浏览器即可
2.2 节省资源
2.3 它们不需要更新,因为所有新的特性都在服务器上执行
3. Web应用程序的缺点
# 特别依赖服务端程序的健壮性,言外之意就是一旦服务端宕机,客户端立马宕机.
4. Web框架
# 框架就是别人写好的模板,我们只需要在模板中固定的位置书写代码即可
# Django框架就是一款专门用来写web应用的框架
http协议
"""
HTTP协议超文本传输协议, 作用:就是规定了服务端和浏览器之间的数据交互格式.
"""
1. 四大特点
1. 基于请求和响应(浏览器发起请求-------->服务端做出响应)
2. 基于TCP/IP协议之上的应用层协议
3. 无状态
# 不保存客户信息
'''不记录用户的信息,后来随着技术的发展,诞生了京东,支付宝,拼多多等,我们每个人要想使用这个网站,就必须登录,要登录,就要记录用户信息,能够记录用户信息的技术有:cookie、session、token...'''
4. 短链接
# 客户端和服务端建立链接之后,客户端发送一些请求,服务端响应一次,然后断开,如果下次再发就要重新链接
# 长链接:客户端和服务端一旦建立链接,不会立马断开,而是中间间隔一段时间,如果双方都没有再次响应则进行断开
eg:客服系统
2. 请求数据格式
2.1 请求首行(HTTP协议的版本号,请求方式)
2.2 请求头(一堆k:v键值对)
2.3 \r\n
2.4 请求体
请求体里面放的都是一些敏感数据
post请求方式有请求体,get请求方式没有请求体,
3. 响应数据格式
3.1 响应首行(HTTP协议的版本号,响应状态码)
3.2 响应头(一堆k:v键值对)
3.3 \r\n
3.4 响应体
#就是服务端返回给浏览器的数据,浏览器渲染到页面上,展示给用户看
响应状态码
'''就是通过用一串简单的数字代码一段复杂的描述信息'''
1XX:服务端接收到消息正在处理,客户端可以继续发送或者等待
2XX:代表请求成功(200 OK),服务端发送了对应的响应
3XX:重定向(进入到A页面,但是内部自动跳转了B页面)
302(临时)
304(永久)
4XX:客户端错误
404:请求资源不存在
403:没有权限
5XX:服务端错误
500 服务器内部错误
请求方式
1. get# 朝服务端要数据
eg: 在网址栏里输入baidu.com
'''没有请求体,可以携带参数,参数跟在了地址栏的后面,使用?&连接'''
https://image.baidu.com/search/detail?ct=503316480&z=0&ipn=false
https://www.baidu.com/s?k=v&k1=v1&k2=v2
https://www.baidu.com/s?wd=美女&ie=utf-8&
2. post# 朝服务端提交数据
eg:你在登录网站的时候,输入用户名和密码,然后把用户名和密码提交到服务端进行验证
'''可以携带参数,参数在请求体中'''
#get与post请求体区别
post携带参数比get携带的参数更加安全
get携带参数大小一般是4kb,post携带参数没有大小限制
get没有请求体,post有请求体
web框架
# 写一个服务端
import socket
server = socket.socket()# TCP UDP
server.bind(('127.0.0.1', 8080))# IP PORT
server.listen(3)# 半连接池
print('开始接收客户端的消息......')
while True:
conn, addr = server.accept()# 等待接收
# 接收客户端发来的消息
# 每一个服务端都用过遵循HTTP协议
data = conn.recv(1024)# 字节(bytes)
print(data)
'''
b'GET /login HTTP/1.1\r\nHost: 127.0.0.1:8001\r\nConnection: keep-alive\r\nCache-Control: max-age=0\r\nsec-ch-ua: "Not_A Brand";v="99", "Google Chrome";v="109", "Chromium";v="109"\r\nsec-ch-ua-mobile: ?0\r\nsec-ch-ua-platform: "Windows"\r\nUpgrade-Insecure-Requests: 1\r\nUser-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36\r\nAccept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9\r\nSec-Fetch-Site: none\r\nSec-Fetch-Mode: navigate\r\nSec-Fetch-User: ?1\r\nSec-Fetch-Dest: document\r\nAccept-Encoding: gzip, deflate, br\r\nAccept-Language: zh-CN,zh;q=0.9\r\n\r\n'
/login
'''
data = data.decode('utf-8')#二进制解码成字符串
current_path = data.split()[1]# 按照空格切割字符串并取索引1对应的数据/index /login /xxx
# http的流式协议
conn.send(b'HTTP/1.1 200 \r\n\r\n')
# 做判断
if current_path == '/index':
conn.send(b'index')
elif current_path =='/login':
conn.send(b'login')
else:
conn.send(b'404 error')
conn.close()
借助于wsgiref模块
内置模块 很多web框架底层使用的模块
功能1:封装了socket代码#socket服务端哪些代码不用我们自己写了
功能2:处理了请求数据#HTTP的数据不用我们自己处理了,它帮助我们处理
1.固定代码启动服务端
2.查看处理之后的request大字典
3.根据不同的网址后缀返回不同的内容>>>:研究大字典键值对
4.立刻解决上述纯手撸的两个问题
5.针对最后一个问题代码如何优化
补充:
1、请求来时,处理请求过来的http格式的数据,封装成方便我们取值的数据格式
2、响应走时,把一些数据封装成http格式数据发给浏览器
from wsgiref.simple_server import make_server
def run(request, response):
"""
:param env:请求相关的所有数据都在env中
:param request: 请求相关数据
:param response: 响应相关数据都在response中
:return: 返回给客户端的真实数据
"""
response('200 OK', []) #响应,括号内为参数. 固定格式,不用管
# print(request) 是一个处理之后的大字典
path_info = request.get('PATH_INFO')#get字典PATH_INFO的v值
if path_info == '/index':
return [b'index']
elif path_info == '/login':
return [b'login']
else:
return [b'404 error']
if __name__ == '__main__':
server = make_server(host='127.0.0.1',port=8080,app=run) # 实时监听127.0.0.1:8080 一旦有请求过来自动给第三个参数加括号并传参数调用
server.serve_forever() # 启动服务端
"""
urls.py ==>路由文件,路由与视图函数的对应关系
views.py==>视图函数,专门用来写后端逻辑功能的
templates文件夹==>专门用来存储前端html文件
"""
# 文件划分之后,要是想增加新功能,只需要在urls.py中写路由,然后在视图函数中写功能即可
动静态网页
1. 静态网页
# 只有页面,数据是写死的,比如html文件
2. 动态网页
# 页面中得数据是从数据库中查询出来的
python中的三大主流web框架
1. Django
# 特点:大而全(重量级的框架),里面自带了很多的功能和模块,里面也带了很多的文件
2. flask
# 特点:小而精(轻量级的框架),自身并没有多少的文件,它也一样可以做django能做的事
它严重依赖第三方模块---------->不停的安装模块---------->所以,它比较依赖第三方
# 当你在flask中安装的模块足够多的时候,也差不多类似于Django了
3. tornado
# 特点:异步非阻塞,并且支持高并发
'''我们目前学习Django框架,后面在学一个flask框架,框架有很多,不必把所有的框架学一遍,因为框架之间大差不差,比如,我们学完Django之后,在去学flask,就简单很多,只需要学习与Django不同的地方'''
其他框架:sanic、fastapi
Django框架
下载安装
1. 版本
1.x 2.x 3.x(不学)
# 我们以1.x为主,附带2.x的区别,1.x和2.x大部分是相同的,在drf中得学习,必须用2.x
注意python解释器版本
djiango1.x--python3.6
djiango2.x--python3.8
2. 安装Django
pip install django===1.11
# 以后我们自己装的第三方模块都在:site-packages文件夹下面
3. 如何验证django是否安装成功
在pycharm终端中/cmd,输入django-admin,看是否有反应,如果有反应就说明安装成功了.(确保Django安装目录D:\Python36\Scripts已在环境变量中)
#出现以下情况解决方式:
1.Django-admin 找不到:将解释器安装位置Scripts加入到环境变量中
2.Django-admin 出现一堆错误:此情况在cmd黑窗口中不会出现,在pycharm终端中可能会出现,解决方法:在pycharm>settings>Tools>Terminal>Shell path切换成cmd.exe
基本命令
1. 创建项目
# 1. 命令行创建
'''你可以提前切换文件夹路径,用来存储django框架的文件位置'''
django-admin startproject 项目名
django-admin startproject myfirst
# 2. pycharm创建
File>New Project>Django>更改相应位置、切换相应解释器、填写应用名app01>create
2. 启动django项目
#第一种cmd启动
1、先命令切换路径到manage.py这一层下面#PS E:\加油努力至少放个屁\4.20> cd myfirst
2、输入命令python36 manage.py runserver # 默认启动在本地电脑上
#如何修改端口号?命令行输入:
python36 manage.py runserver 127.0.0.1:8080
'''出现Starting development server at http://127.0.0.1:8000/代表启动成功'''
#第二种pycharm启动
在上边导航栏中点击绿色三角按钮启动
"""Next, start your first app by running python manage.py startapp [app_label]."""
3.创建应用
"""
Django框架就是一款专门用来开发web应用的
django这个框架类类似于是一所大学(空壳)
应用相当于是一所大学里面的二级学院
所以,应用是可以有多个的
eg:我们使用django开发一个淘宝出来
用户相关的功能----------->user
订单相关的功能------------>order
客服相关的功能------------>kefu
发货相关的功能------------>fahuo
...
每一个应用就是一个独立的功能
"""
# 每一个django项目至少要有一个应用!!!
#如何创建应用
1. cmd执行命令创建
python36 manage.py startapp 应用名
python36 manage.py startapp app01
''' 应用名都应该做到见名知意:
为了方便教学,我们统一使用app01/02/03/04...'''
2. pycharm创建应用在pycharm创建项目时直接填写应用名
File>New Project>Django>更改相应位置、切换相应解释器、填写应用名app01>create
2.1pycharm导航栏
Tools>run manage.py task>终端输入startapp 应用名# 在这个里面命令前面的python3 manage.py省略不写
4. 当命令创建应用出来之后,把应用名添加到配置文件中
# 去配置文件setting.py中去注册应用,以后每创建出来一个应用,都要去这里面去注册,如果不注册,你创建出来的应用,不生效.
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
# 'app01.apps.App01Config', # 注册应用,全称
'app01', #将新创建的应用名添加
]
- 注意事项
1. 一个pycharm窗口只打开一个django项目
2. 以后再django项目所有的文件名都不能出现中文.
- 命令行创建和pycharm创建的区别
#命令行创建:
1. 命令行创建的项目没有templates文件夹
需要手动创建的templates文件夹
2. 命令行创建settings.py文件中:
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [], # 默认没有东西
},
]
需要拼接路径到settings.py的TEMPLATES中
'DIRS': [os.path.join(BASE_DIR,'templates')]
#pycharm创建
1. pycharm创建的项目会自动创建templates文件夹
2.pycharm创建settings.py中:
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [BASE_DIR / 'templates'] # pycharm创建出来的有东西
}
# 在settings.py TEMPLATES文件中统一改成:
'DIRS': [os.path.join(BASE_DIR, 'templates')]
- 主要文件介绍
myfirst # 项目名称
app01 # 应用名称
migrations # 它是数据库迁移记录----------->跟数据库相关的时候才会用到
__init__.py
admin.py # 跟后台相关的
apps.py # 跟注册一些东西相关的
models.py # 这个是跟数据库相关的文件(重要)
tests.py # 这个是测试文件
views.py # 视图函数----------->主要写一些功能逻辑
app02
myfirst
__init__.py
settings.py # django框架的配置文件
urls.py # 路由文件:后缀和视图函数的对应关系
wsgi.py # 是一个服务器------->wsgiref(支持的并发量小)----------->uwsgi服务器----->支持的并发量高
db.sqlite3 # django自带的小型数据库,方便我们测试使用
manage.py # 这个是django框架的启动文件,入口文件
"""
网址后缀 路由
函数 视图函数
类 视图类
重要名词讲解
urls.py 路由层
views.py 视图层
models.py 模型层
templates 模板层
"""
django三板斧
1. HttpResponse#返回给浏览器字符串类型的数据
2. render#返回html页面并且支持传值
3. redirect#重定向,括号内写url地址
def func(request):
print('from func')
# return HttpResponse("ok!!!") # 里面写的都是字符串
# return render(request,'index.html') #加载html文件,括号内必须写两个参数
# return redirect('http://www.baidu.com') # 重定向
return redirect('/home/') # 重定向,括号内写url
- 例
views.py代码内容:#views.py文件每创建一个函数都要添加到urls.py文件
from django.shortcuts import render,HttpResponse,redirect
# Create your views here.
def index(request):#函数括号内必须要填一个参数
print('index')
def func(request):
# print('func')
# return HttpResponse('ok')
# return render(request,'index.html')#加载html文件页面
# return redirect('https:www.baidu.com')#重定向跳转页面
return redirect('/home/')#
def home(request):
return HttpResponse('home页面')
templates目录中index.html代码如下
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
{# <script src="jquery.js"></script>#}
{# <script src="bootstrap-3.4.1-dist"></script>#}
{# <style>#}
{# #}
{# </style>#}
</head>
<body>
<h1>index页面</h1>
</body>
</html>
urls.py代码内容如下:
ufrom django.conf.urls import url
from django.contrib import admin
from app01 import views
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^index/', views.index),#url方法的第二个参数一直写的都是函数内存地址 不能加()调用,views.index为点views文件index函数
url(r'^func/', views.func),#url方法的第二个参数一直写的都是函数内存地址 不能加()调用,views.index为点views文件index函数
url(r'^home/', views.home),#url方法的第二个参数一直写的都是函数内存地址 不能加()调用,views.index为点views文件index函数
]
配置文件的介绍
SECRET_KEY = '0yge9t5m9&%=of**qk2m9z^7-gp2db)g!*5dzb136ys0#)*%*a' # 加盐处理
DEBUG = True # 调试模式, 等项目上线的时候,改成False
ROOT_URLCONF #根路由文件
# 配置数据库
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',#默认sqlite3数据库
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
}
}
# 改语言
LANGUAGE_CODE = 'en-us'# 语言
#LANGUAGE_CODE = 'zh-hans'#改成中文
# 改时区
TIME_ZONE = 'Asia/Shanghai'
# TIME_ZONE = 'Asia/shanghai'改成上海时区
USE_TZ = True#数据库中用的时区
STATIC_URL = '/static/'#静态文件配置相关
静态文件的配置
"""
我们在Django中一般把html文件放到tempates文件夹下面
把静态文件放到static文件夹下面
"""
静态文件:不怎么经常变化的文件,主要针对html文件所使用的到的各种资源就是我们常见的:CSS文件、JS文件、img、我们的第三方前端框架:bootstrap相关的
以登录页面为例,我们每次编写html代码时渲染页面都需要导入CSS文件、JS文件等资源文件,较为麻烦,所以
1、手动创建static文件项目根目录下
#Django没有创建static文件夹,需要我们手动创建static文件在项目根目录下,名字可以不叫static,但是大家都叫static
2、将静态文件CSS文件、JS文件、img、第三方前端框架:bootstrap相关的复制到static文件夹目录下
'''在static文件夹下面还可以按照功能的不同,进行目录的划分继续创建目录
css目录
js目录
img目录
utils目录/plugins目录/libs目录/others目录/不创
'''
# 在浏览器中输入网址,如果找不到,说明对应的服务端没有开设对外访问的接口
解决思路:默认情况下无法访问 因为我们没有提前开设静态文件资源的访问接口
3、在seetings.py文件进行配置路径
STATIC_URL = '/static/'#令牌 如果想在Django中访问静态文件,必须使用以static开头
STATICFILES_DIRS = [
os.path.join(BASE_DIR, 'static')]# 存储静态文件资源的目录名称
以后凡是找静态文件,都从这个列表中得路径去找
# STATICFILES_DIRS = [
# '/static/css/my.css'
# ]
'''若是有多个路径,查找顺序是代码从上至下依次开始找,找到就停止,反之报错
STATICFILES_DIRS = [
os.path.join(BASE_DIR, 'static')
os.path.join(BASE_DIR, 'static1')
os.path.join(BASE_DIR, 'static2')
]'''
4、在html文件引入路径
第一种方式:
<link rel="stylesheet" href="/static/bootstrap-3.4.1-dist/css/bootstrap.min.css">
<script src="/static/js/jquery.min.js"></script>
src="/static/bootstrap-3.4.1-dist/js/bootstrap.min.js"></script>
这种方式需要在配置文件中加入代码STATICFILES_DIRS = [
os.path.join(BASE_DIR, 'static')]
第二种动态引入方式:
{% load static %}#{% %}是djiango提供的语法
<link rel="stylesheet" href="{% static 'bootstrap-3.4.1-dist/css/bootstrap.min.css' %}">
<script src="{% static 'js/jquery.min.js' %}"></script>
<script src="{% static 'bootstrap-3.4.1-dist/js/bootstrap.min.js' %}"></script>
这种方式不需要在配置文件中加代码STATICFILES_DIRS = [
os.path.join(BASE_DIR, 'static')]
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
{% load static %}
<link rel="stylesheet" href="{% static 'bootstrap-3.4.1-dist/css/bootstrap.css' %}">
<script src="{% static 'js/jquery.js' %}"></script>
<script src="{% static 'bootstrap-3.4.1-dist/js/bootstrap.js' %}"></script>
</head>
form表单
<form action="/login"> 控制数据提交的地址
1.action="" 数据默认提交给当前页面所在的地址
2.action="https://www.baidu.com/" 完整地址,指定提交为该地址
3.action="/index/" 只写后缀,默认拼接本地地址朝当前服务端的index地址提交(http://127.0.0.1:8000/index/)
method 控制数据提交的方法
1.get 默认
2.post 可以更改为post method='post'
请求方法补充
get
朝服务端索要数据 也可以携带一些额外的要求
携带额外数据的方式: URL?xxx=yyy&uuu=zzz
问号后面携带数据的大小是有限制(2KB)的并且不能携带敏感数据
post
朝服务端提交数据
携带额外数据的方式: 请求体
请求体携带数据安全性较高并且没有大小限制
<head>
<meta charset="UTF-8">
<title>Title</title>
{% load static %}
<link rel="stylesheet" href="{% static 'bootstrap-3.4.1-dist/css/bootstrap.css' %}">
<script src="{% static 'js/jquery.js' %}"></script>
<script src="{% static 'bootstrap-3.4.1-dist/js/bootstrap.js' %}"></script>
</head>
<body>
<div>
<div class="container">
<div class="row">
<h1 class="text-center">登录页面</h1>
<form action="/do_login/" method="POST">{#form action="/do_login/"注意末尾斜杠,浏览器会自动在末尾加斜杠,有的浏览器则需手动在末尾加上/#}
{#默认什么都不写就是GET请求方式,加method="POST"就是修改请求方式为POST的#}
{#修改请求方式为POST那么需要到配置文件中将MIDDLEWARE某行注释掉#}
<div class="form-group">
username:<input type="text" class="form-control" name="username">
password:<input type="password" class="form-control" name="password">
</div>
<div class="form-group">
<input type="checkbox" name="hobby" value="1">
<input type="checkbox" name="hobby" value="2">
<input type="checkbox" name="hobby" value="3">
</div>
<input type="submit" class="btn-warning">
</form>
</div>
</div>
</div>
</body>
# 我们以后再提交post请求方式的表单的时候,需要做一件事情,去配置文件中找到MIDDLEWARE,前期发送post请求需要注释掉配置文件中的某一行
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
# 'django.middleware.csrf.CsrfViewMiddleware',#这里需要注释,解决post提交不成功,GET请求方式则不需要注释掉
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
request对象的方法
request.method 获取请求方式 结果是纯大写的字符串数据
print(request.POST) # 接收post请求提交过来的数据
print(request.POST.get('username')) # kevin获取列表最后一个数据值
print(request.POST.get('hobby')) # 3 2
print(request.POST.getlist('hobby')) #['1', '2', '3']获取整个列表数据
'''get方法取列表最后一个元素值,getlist取列表所有的元素值'''
print(request.GET)获取网址问号后面携带的数据
print(request.GET.get('username'))获取列表最后一个数据值
print(request.GET.getlist('hobby'))获取整个列表数据
from django.shortcuts import render,HttpResponse
def login(request):
#根据不同的请求方式,得到用户输入数据
print(request.method)#GET,查看当前请求方式
print(type(request.method))#<class 'str'> 为字符串类型
if request.method =='GET':
print(request.GET)#获取GET请求方式提交的数据
elif request.method =='POST':
print(request.POST)#<QueryDict: {'username': ['22'], 'password': ['33']}>获取POST请求方式提交的数据
print(request.POST.get('username'))#22
print(request.POST.get('hobby')) # 3 2
print(request.POST.getlist('hobby')) # ['1', '2', '3']
return render(request,'login.html')
def do_login(request):
#处理表单提交过来的数据
#接收前端数据
print('嘿嘿嘿')
return HttpResponse('do_login')
"""
在视图函数中针对不同的请求代码编写套路
if request.method == 'POST':
return HttpResponse()
return HttpResponse()
"""
链接数据库(MySQL)
pycharm链接数据库(MySQL)
# 这个时候pycharm就是数据库的客户端了,类似于Navicat,
1.pycharm初次连接数据库 需要下载驱动
pycharm初次连接数据库 点开界面右侧 database>左上角+>Data Source进入选择数据库后>输入数据库用户名与密码选择库名>下载驱动文件>测试是否成功>Apply
2.参考下方截图基本操作即可
Django链接数据库(MySQL)
# django默认自带的小型数据库sqllite3,功能比较少,主要用于本地测试,我们实际项目中都会替换掉它
默认配置sqlite3
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
}
}
1.修改settings.py配置文件为MySQL数据库
DATABASES = {
# 'default': {
# 'ENGINE': 'django.db.backends.sqlite3',
# 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
# }默认为sqlite3数据库
'default': {#修改配置数据库
'ENGINE': 'django.db.backends.mysql',#引擎
'NAME': 'db1',#数据库名
'HOST': '127.0.0.1',#连别人主机就填别人的地址
'PORT': 3306,
'USER': 'root',
'PASSWORD': '123',
'CHARSET': 'utf8',
}
}
# 以上配置改完之后,框架启动不起来了
'''
djang框架底层链接MySQL用的模块是MySQLdb模块,这个模块的兼容性很差,所以我们不用,我们需要人为的把MySQLdb模块改为pymysql模块
'''
2.如何修改pymysql模块呢?
Django1.X版本的框架任意目录__init__.py文件中加入以下代码(pycharm须先安装pymysql模块pip install pymysql):
import pymysql#这句话的意思其实就是猴子补丁
pymysql.install_as_MySQLdb()
Django1.X版本每次启用pymysql模块都需要加上以上代码
Django2.X版本每次启用不需要加以上代码
django2.X及以上都可以直接通过下载mysqlclient模块解决
pip3.8 install mysqlclient
ps:该模块windows下载问题不大 主要是mac电脑可能有问题
'''注意Django2.X版本链接mysql时报错:AttributeError: 'str' object has no attribute 'decode
出现这个错误之后点击异常信息的地址,打开 operations.py 文件,将 decode改为encode(将query = query.decode(errors='replace')改成query = query.encode(errors='replace')
''''
Django的ORM操作
ORM: 对象关系映射
作用:我们以后再操作数据库的时候,就不用在写原生sql语句,用面向对象的代码去写,然后他给你翻译成原生sql语句。
'''我们的ORM相关代码写在哪里呢?在models.py文件中写'''
缺点:封装程度太高,ORM的sql执行效率没有原生sql执行的效率高,这个效率的影响暂时忽略
# 关系映射:
表 >>>: 类名
记录 >>>: 对象
字段 >>>: 属性(对象点名字)
1. 创建一张表出来
from django.db import models
# 每一个类都必须继承models.Model
class Author(models.Model):#类名就是表名
#mysql语法:id int primary key auto_increment
id = models.AutoField(primary_key=True)#自增主键,AutoField=auto_increment
#mysql语法:username varchar(32)
username = models.CharField(max_length=32)#max_length参数必填
#mysql语法:password varchar(32)
password = models.CharField(max_length=32)
''''由于每张表都应该有一个主键字段,并且主键字段名都叫id,如果满足这两个条件,那么可以省略不写主键字段,Django自动创建主键字段'''
class students(models.Model):#人为不写创建主键id的代码,那么Django会自动创建主键id,倘若所要创建的主键字段名不为id那么就要自己创建主键
students_name=models.CharField(max_length=32)
students_age=models.IntegerField()
2.执行数据库迁移命令
#第一种方式:打开pycharm终端执行以下命令:
python36 manage.py makemigrations # 将操作数据记录到 APP02\migrations\0001_initial.py
python36 manage.py migrate # 将数据迁移到数据库上
#第二种方式:
pycharm中导航栏Tools>Run manage.py >控制台执行命令makemigrations>控制台执行命令migrate
'''执行数据库迁移的命令两条缺一不可!!!只要修改了跟数据库相关的代码,都要执行命令'''
执行完以上命令就能到Navicat看到创建的表了,截图如下
orm针对字段的增删改查
#增删改查都要执行数据库迁移命令,迁移命令指定app应用名,若不指定应用名默认将所有的应用相同表名字段都修改
1.增加字段:直接增加代码
class teachers(models.Model):
students_name=models.CharField(max_length=32)
students_age=models.IntegerField()
teacher_age=models.IntegerField()
teacher_gender=models.CharField(max_length=32,default='bb')#增加
"""增加字段可能出现的问题 解决方式给字段增加默认值"""
2.删除字段:代码注释就删除了,然后再执行迁移命令
# teacher_gender=models.CharField(max_length=32,default='bb')
3.修改字段:在原先字段代码修改就行
teacher_gender=models.CharField(max_length=32,default='bb')
teacher_gender1=models.CharField(max_length=32,default='bb')#teacher_gender修改为teacher_gender1
数据的增删改查
from app01 import models
res=models.UserInfo.objects.filter(username=username, password=password).first()#first()取第一条
'''filter(username=username, password=password)里面的条件是and关系'''
# print(res[0]) # <QuerySet [<UserInfo: UserInfo object>]>
# print(res[0].username) # <QuerySet [<UserInfo: UserInfo object>]>
# print(res[0].password) # <QuerySet [<UserInfo: UserInfo object>]>
if res:
# print('登录成功')
models.UserInfo.objects.create(username='tank', password='123')
else:
print('用户名或者密码错误')
1.增加数据
第一种方式:
models.表名.objects.create()
res=models.UserInfo.objects.create(username=username,password=password)
第二种方式:
res=models.表名(username=username,password=password)
res.save()#保存
2.查询数据
models.表名.objects.filter()#filter相当于where
res = models.UserInfo.object.filter(username=username) # 结果是个对象
res[0].字段名 可以拿到该字段的数据
res=models.objects.filter().all()
"改,删都需先查询到该数据才能操作"
3.修改数据
第一种方式:
models.表名.objects.update(**kwargs)
models.UserInfo.objects.filter(pk=edit_id).update(username=username, password=password) # 多条数据通过id筛选
第二种方式:
res=models.表名.objects.filter(pk=edit_id).first()
res.username=username
res.password=password
4.删除数据
# 物理删除,直接从磁盘中把数据删掉了
models.表名.objects.delete()
models.UserInfo.objects.filter(id=2).delete()
# 软删除
models.UserInfo.objects.filter(pk=del_id).update(is_delete=True)
标签:文件,models,py,request,django,Django
From: https://www.cnblogs.com/Super-niu/p/17586295.html