文章目录
- Django静态文件及相关配置
- 静态文件前言
- 静态文件相关配置
- form表单
- request对象
- request请求结果
- GET请求
- POST请求
- pycharm连接数据库
- Django连接MySQL
- Django ORM简介
Django静态文件及相关配置
在此篇博客我将以一个用户登录页面来引入相关知识
首先我们先编写一个html页面
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title><script src="../js/jquery-3.7.1.min.js"></script><script src="../bootstrap-3.4.1-dist/js/bootstrap.min.js"></script><link rel="stylesheet" href="../bootstrap-3.4.1-dist/css/bootstrap.min.css">
</head>
<body><div class="container"><h1 class="text-center">登录页面</h1><div class="row"><div class="col-md-8 col-md-offset-2"><form action="" method="post"><div class="form-group">username: <input type="text" class="form-control" name="username"></div><div class="form-group">password: <input type="password" class="form-control" name="password"></div><div class="form-group"><input type="submit" class="btn btn-block btn-success" value="登录"></div></form></div></div></div>
</body>
</html>
静态文件前言
不怎么经常变化的文件,主要针对html文件所使用到的各种资源,
比如css文件、js文件、img文件、第三方框架文件
在Django中针对静态文件资源需要单独开设一个目录统一存放,
这个目录名称统一命名为static目录
static目录 该目录下类型文件居多可再多分├── css目录├── bootstrap.min.css└── js目录├── jquery-3.7.1.min.js└── bootstrap.min.js└── img目录├── utils目录/plugins目录/libs目录/others目录/不创建目录
资源访问
我们在地址栏之所以可以输入路由获取到相应的资源登录资源,是因为程序员提前开设了相对应的资源接口,如果在网址输入http://127.0.0.1:8000/admin,就能访问相对应的接口资源,反之如果没有开设相对应的接口则访问不了
静态文件资源访问
在django中直接引入css和js,是不能直接使用动态效果的,要静态文件配置添加,添加了Bootstrap之前要添加jquery。默认情况下是无法访问的,是因为我们没有提前开设静态文件资源的访问接口。如下图所示
而login能请求成功是因为在后端已经开设了这个http://127.0.0.1:8000/login/这个端口,所以浏览器在地址栏输入对应的链接后就能访问;但是请求URL:http://127.0.0.1:8000/static/bootstrap-3.4.1-dist/css/bootstrap.min.css是因为后端没有开设这个端口,所以浏览器朝这个网址请求资源就访问不了。
那么怎么解决?
理论上我们应该在urls填写相对应的关系,但是静态文件太多了,所以django专门为静态文件开设了一个static文件资源接口
静态文件相关配置
1.如何配置静态文件配置?
首先在settings里面找到最后STATIC_URL = ‘/static/’,在此代码的下面配置static的所有资源的路径
2.静态文件令牌
STATIC_URL = './static/' # 访问静态文件资源的令牌STATICFILES_DIRS = [os.path.join(BASE_DIR, 'static'), # 存储静态文件资源的目录名称os.path.join(BASE_DIR, 'static1') # 存储静态文件资源的目录名称(非要用别的名称设定目录也是可以的)]'当令牌正确之后,会拿着后面的路径依次去到列表中自上而下的查找,一旦找到就返回'
查找顺序:静态文件令牌>>>>接口资源文件(自上而下,找到就截止),只有令牌对了才有资格访问接口文件资源
要是我们就是想切换接口令牌呢?
当那个时候我们就得需要去到所有使用到令牌的地方去一一修改,但是有的时候就浏览器会请求临时缓存内容发送给我们,我们不可能一个一个去改static,这样太麻烦了,所以我们可以直接动态解析
3.静态文件令牌动态解析
静态文件匹配<link rel="stylesheet" href="/static/bootstrap-3.4.1-dist/css/bootstrap.min.css"><script src="/static/bootstrap-3.4.1-dist/js/bootstrap.min.js"></script>
如果我们想要更改令牌的话2,我们需要把上门静态文件配置改为下面的模版语法(即可动态解析)
django提供的模版语法{% load static %} ,相对于模块'为了防止令牌一直切换,设置一个专门监听令牌的方法,设置之后会有一个动态解析后端设置前端自动解析设置相同'{% load static %}<link rel="stylesheet" href="{% static 'bootstrap-3.4.1-dist/css/bootstrap.min.css' %}"><script src="{% static 'bootstrap-3.4.1-dist/js/bootstrap.min.js' %}"></script>
这样修改完后,我们后面每次想改令牌,直接在settings将STATIC_URL='/static/'
修改为自己想要的名称即可,如STATIC_URL= '/UpdateStatic/'
,后面django会自动为我们动态解析的,如下图
form表单
action 控制数据提交的地址1.action="" 数据默认提交当前页面所在的地址2.action="http://www.baidu.com" 指定提交完整的网址3.action="/login" 超当前服务端的login地址提交
请求方式补充
1.get请求:朝服务端索要数据,也可以携带一些额外的要求。
携带额外数据方式:在地址栏里面,URL?xxx=yyy&uuu=zzz,但是问号后面携带的数据大小是有限制的(2-8kb),并且不能携带敏感数据(密码)
2.post请求:朝服务端提交数据
携带额外数据的方式:请求体,请求体携带数据安全性较高并且没有大小的限制
前期发送post请求需要再settings配置文件中注释掉这行代码
如下:
get请求、post请求如下
form表单需要注意的点
- 关于请求方法
- 获取用户标签要加上name属性,不加name属性时在后端是接收不了的
- 修改settings里面的配置
request对象
request请求结果
语法 | 说明 |
---|---|
request.method | 获取请求方式 结果是纯大写的字符串 |
request.POST | 获取POST请求发送来的普通数据(不包含文件) |
request.POST.get() | 默认只获取列表中最后一个数据值 |
request.POST.getlist() | 获取键对应的整个列表 无论有几个数据值 |
request.GET | 获取url后面携带的非敏感数据 |
request.GET.get() | 默认只获取列表中最后一个数据值 |
request.GET.getlist() | 获取键对应的整个列表 无论有几个数据值 |
Request函数会通过不同的请求方式触发,并且需要执行不同的业务逻辑代码
def index(request):return HTTpReponse('hello world!')
作用:浏览器访问某一个URL后,通过路由找到对应的视图里面某个函数,然后将浏览器的请求传递给这个函数,这也就是为何要定义一个形参了,而通常形参名都是:request,这是一种规范。
request内包含了浏览器想Django服务端发送的请求,常见发送请求的方法有两种:GET、POST
它们携带请求的形式是不同的。
GET请求
index.html文件(前提是已经搭建好了Django的基本环境)
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>{% load static %}<script src="{% static 'js/jquery-3.7.1.min.js' %}"></script><script src="{% static 'bootstrap-3.4.1-dist/js/bootstrap.min.js' %}"></script><link rel="stylesheet" href="{% static 'bootstrap-3.4.1-dist/css/bootstrap.min.css' %}">
</head>
<body><div class="container"><h1 class="text-center">登录页面</h1><div class="row"><div class="col-md-8 col-md-offset-2"><form action="" method="get"><div class="form-group">username: <input type="text" class="form-control" name="username"></div><div class="form-group">password: <input type="password" class="form-control" name="password"></div><div class="form-group"><input type="submit" class="btn btn-blcok btn-success"></div></form></div></div></div>
</body>
</html>
使用form表单以get方法提交请求,action不填写的话,默认向当前地址提交。
GET方法提交请求的方式:将请求数据携带在URL内,我们在Django内通过debug查看一下。(需要先提交一遍,保留url的参数再开启debug,然后再刷新一下页面,因为debug一开启就进入阻塞了)
request内包含了浏览器提交请求的方法,在对应请求方法里面包含了携带的数据,我们可以提取这些数据进行处理。从上图可以看出,这些数据是一个字典形式的,而字典的key就是我们在HTML文件内输入框的
name属性值。
view.py文件中
from django.shortcuts import render,HttpResponse,redirectdef index(request): # print(request.method, request) # 查看请求提交的方法username = request.GET.get('username')password = request.GET.get('password')# 获取get方法提交请求携带的数据,根据字典形式取值:key值就是name属性值print(username,password)return render(request,'index.html')
浏览器打开效果:
推荐字典key的取值方式使用.get(key)
,这样如果key不存在的话则返回一个None
,而使用[key]
取值的话,key不存在的话则报错。
但是通常使用GET方式提交数据是不安全的,相对这种账号、密码登录的功能,使用的都是POST请求。
注意:request.GET获取的是URL?后面的内容
只要用户访问的URL令牌没有问题,依然可以交给对应的视图函数处理:如
http://127.0.0.1:8080/index/?username=jack&password=000
这要用户输入这种URL,提交到后端只会识别ip+端口后面的/index/,而
?
后面的内容则会被当做额外数据提交到后端。所以会将这个请求交给index视图函数。然后使用request.GET
就可以把那个额外数据取出来了。我们在post请求下面一起演示
POST请求
先将表单的提交请求方式修改为POST:
使用浏览器打开:
可以发现,无法正常显示我们的HTML文件,查看报错信息发现是csrf原因,目前我们不需要了解为什么会报这个错误,解决方案就是,在settings.py文件内:
此时我们再重启一下Django,使用post方法提交就不会出现这个错误信息了。
我们在views.py内使用debug看一下POST请求的内容:
根据上图,我们可以发现request有两个属性都存放了浏览器提交请求的数据:POST、body。而使用GET方法提交时没有发现body属性存有值,那么我们来逐个打印一下,看看它们的不同之处。
POST属性可以理解为存储了字典形式的值,而body内存储的是二进制。所以方便取值我们还是使用POST来解决。
演示GET属性与POST属性一起使用:
修改URL,表单提交方式为post
可以发现,GET属性获取的只是URL里?后面的内容,而POST则是获取用户真正输入的数据。
get()与getlist()
Django内有一个很奇怪的现象,从上图中我们就可以发现,明明key对应的是一个列表,我们get()不是取出一个列表,而是将列表里面的值取出来。这是Django内自带的一个取值方式,而不是我们平常所见取字典值的get()。
其实这里的get()取出的是列表的内的最后一个值,我们修改一下HTML页面再提交就明白了
可以发现,现在有两个name属性值相同的input,那么我们都输入完后再提交一次看看。
从上图可以发现,get()取出的是列表的最后一个值,那么getlist()就很明确了,直接获取整个列表。
总结:
部分视图函数内,我们会写两种情况,第一种就是如果浏览使用POST传递了数据,我们执行的操作,另一种就是浏览器使用GET请求我们应该执行的操作。
通常访问页面发送的都是GET请求,如果是一个登录界面的话,视图函数会这样写:
def login(request):if request.method == 'POST':请求信息提取过程....if 账号密码校验成功:登录状态绑定...return redirect(重定向到主页)else:return 返回账号或者密码错误结果return render(request,'登录页面.html')
pycharm连接数据库
1.pycharm初次连接数据库,都要下载相应的驱动,驱动不行就换驱动,验证的话就是登录用户名(端口和地址) 库名,验证登录就用test connection
2.登录管理员账户和密码,连接你需要的数据库(库要提前创建好),在连接之前可以先点击Test Connection 测试连接是一次。注意:在公司不能是管理员的用户登录的!
3.成功连接成功
Django连接MySQL
django自带的sqlite3是一个小型的数据库,功能比较少,主要是用于本地测试。实际项目都会替换它的
1.修改配置文件中数据库设置成django连接MySQL
django配置文件中默认的是sqlite3数据库
DATABASES = {'default': {'ENGINE': 'django.db.backends.sqlite3','NAME': os.path.join(BASE_DIR, 'db.sqlite3'),}
}======================================================django连接MySQL要修改上述配置
1.第一配置文件中配置
DATABASES = {'default': {# 'ENGINE': 'django.db.backends.sqlite3', # 修改成MySQL数据库# 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), # 连接数据库名称 先创建好才能指定'ENGINE': 'django.db.backends.mysql', # 修改成MySQL数据库'NAME': 'user', # 连接数据库名称 先创建好才能指定'HOST': '127.0.0.1', # 网址'PORT': 3306, # 端口'USER': 'root', # 指定用户#'PASSWORD': '123', 因为我的mysql没有设置密码所以可以不用填写'CHARSET': 'utf8' # 字符编码}
}注意,左边的名字都要大写!!!!另外链接可能会出现问题 需要指定链接MySQL模块MAC Django2.2.2 版本需要在项目或者应用目录下的__init__.py中编写一行代码import pymysql pymysql.install_as_MySQLdb()出现编码问题 点击蓝色链接 把decode改成encode即可MAC不需要安装mysqlclientWIN Django2.2.2版本不需要再项目目或者应用目录下的__init__.py中编写一行代码WIN需要安装mysqlclient
2.手动改动将默认mysqldb改为pymysql
django默认用的是mysqldb模块链接MySQL, 但是该模块的兼容性不好 需要手动改为用pymysql链接,需要指定模块
django1.X版本需要在项目目录下或者app目录下的__init__.py编写代码
import pymysqlpymysql.install_as_MySQLdb()
django2.X及以上都可以直接通过下载mysqlclient模块解决
pip3.8 install mysqlclient
ps:该模块windows下载问题不大 主要是mac电脑可能有问题
Django ORM简介
ORM:Object对象,Relations关系、Mapping映射。简称:对象关系映射
优点:在Django中操作数据库就不用写原生的SQL语句,而是使用面向对象的语法和一些方法来操作数据库
缺点:代码的封装程度太高,导致的问题:执行效率下降了 ,目前可以忽略,需要自己写原生SQL语句
对象关系映射是通过面向对象的方式来操作数据库,这就需要对应的关系映射,数据中可以分为库,表,字段信息,一条条数据,而需要用面向对象的关系去对应。于是就有了下面对应关系。
- 数据库 ======= 面向对象模型
- 表 ======= 类
- 字段 ======= 类属性
- 记录 ======= 每个实例
什么是ORM?对象关系映射(Object Relational Mapping 简称ORM)模式是一种为了解决面向对象与关系数据库存在的互不匹配的现象的技术ORM框架是连接数据库的桥梁 只要提供了持久化类与表的映射关系 ORM框架在运行时就能参照映射文件的信息 把对象持久化到数据库中为什么用ORM?当我们实现一个应用程序时不用ORM 我们可能会写特别多数据访问层的代码 从数据库保存、删除、读取对象信息 而这些代码都是重复的而使用ORM则会大大减少重复性代码 对象关系映射主要实现程序对象到关系数据库数据的映射类映射成表 对象映射成记录 对象点属性映射成字段对应的值ORM的存在可以让不会MySQL的python程序员 使用python的语法简单快捷的操作MySQL1.先去应用目录下models.py中编写模型类class User(models.Model): # 类似于定义了表名 id = models.AutoField(primary_key=True) # 类似于新建了记录ID主键name = models.CharField(max_length=32) # 类似于定义了普通varchar字段pwd = models.InteerField() # 类似于定义了id int primary key auto_incrementname varchar(32)pwd int'''注意括号内可以添加多个属性'''2.数据库迁移与同步命令2.1>将models中有关数据库的操作记录下来到migrations文件夹中python38 manage.py makemigrations2.2>将操作命令真正的去操作数据库python38 manage.py migrate当修改了models中与数据库相关的代码 都必须执行以上两个命令 要不然无效ps:可以简写 也可以指定应用单独迁移/同步 Tools>Run Manage.py Task3.表的主键在orm中 可以不写 orm会自动帮你添加一个id的主键如果你需要主键的名称不叫id 只能自己创建