Django的日常-数据传输
Django的日常-1
Django中最常用的三个东西
之前我们介绍了Django的安装和创建,以及其基本原理,接下来我们就逐步介绍Django里面常见的一些东西,以下三种通常都是用来作为返回值的.
HTTPresponse
用来返回字符串
return HttpResponse('hello world~')
# 会返回一个字符串,即屏幕上只会剩下这一个字符串,用处比较有限,不过也算有用
render
用来返回一个网页,这个用处比较大,比如
def reg(request):
return render(request,'reg.html')
# request的用处我们在下面会介绍,这个例子的意思就是最终会返回一个reg.html网页,通常我们在浏览网页的时候,网页之间的切换也许会用到这个,也许不会,这只是一种选择.
redirect
重定向,重定向的概念我们在之前介绍http协议的时候介绍过,所以我们定义重定向的话可以直接将当前网页转到重定向后的网页.
def home(request):
return redirect('https://baidu.com')
# 即在触发了这个函数之后就会直接跳向重定向的网页
静态文件相关
网站所用到的静态文件通常包括以下几类,即自己写好的JS,自己写好的CSS或者我们所引用的第三方框架,bootstrap,fontwesome,sweetalert等等.
在之前我们了解到,在引入第三方框架的时候我们可以选择用cdn在线缓存的文件,或者自己下载下来,用本地的静态文件.这里我们选择用静态文件,然后就需要把这些静态文件统一放在一个文件夹里面,通常我们会放在一个新建的名为static的文件夹里,约定俗成的,没什么道理.
但是要注意的一点是,在我们把所有的静态文件都扔到文件夹里之后,Django并不能很准确的去识别这个路径,就算我们在html界面里用根目录来引用这些文件也不行,Django本身找不到,所以,我们要配置一下路径
配置静态文件的访问资源是在根目录下的settings.py
文件里,在最后我们会看到
# settings.py文件的最下方
STATIC_URL = '/static/'
# 这是我们访问静态资源的接口前缀,很重要,就是我们输网址的时候要写的接口前缀
# 然后我们需要在这个语句下面加上这样一个配置项
STATICFILES_DIRS = [
os.path.join(BASE_DIR, 'static'), # 拼接路径名
]
在添加好路径之后,我们在html文件引入方式也需要改变,如下:
# **.html文件,<head>在这里面添加以下语句</head>
{% load static %}
<link rel="stylesheet" href="{% static '静态文件所在地址'%}">
# 这样都配置过之后,我们才能正确的引入这些静态文件,并正确引用他们.
form表单的get与post
form表单是我们熟悉前端的时候学到的东西,其标准格式如下
<form action="" action="" method="post">
# action参数可以写的是:
1. 空着,会默认向当前页面的地址提交
2. 只写后缀,如/index,/admin等,则会在前面自动拼接上当前的网址和端口,然后拼接上所写的后缀
3. 写全路径
# method参数,默认是get,还可以写post
我们要知道这两者的区别,get,当我们输入网址,进入网址的时候,此时服务端是已经收到了一个get请求的,所以我们才能接收到一个网页,这个网页就是服务端对于我们的get返回的一个返回值,但是get请求本身是有一些问题的,主要体现在以下两点:
1. get请求不安全,因为get请求在携带参数的时候是直接在url?后面添加的,比如?username=admin&password=159789
所以这种情况下,如果是输入的账号密码然后发送一个get请求,是非常不安全的
2. get请求所能携带的参数是有长度限制的,根据每个浏览器的不同,都会有不同长度的限制
# 在了解了以上内容之后,如果我们想要提交post请求,除了把method里面参数改成post之外,还需要注释掉一个语句,这个语句对于我们初学者来说没有用处,还会影响整个项目的运行.
# 其位置仍然在settings.py文件里,我们需要注掉的就是'django.middleware.csrf.CsrfViewMiddleware'这个语句
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
# 'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
神奇的request
requests是我们写每一个views方法的时候都会在括号里传的参数,其最大的作用就是负责前端和后端数据的交互,后端所收到的前端的信息几乎全都来自于requests中,request是一个对象,而且是一个非常全面且强大的对象,我们可以通过这个对象点出来很多东西,比如:
request.MATE
# mate所包含的是几乎所有的HTTP的请求信息,以k:v键值对的形式存储的
request.scheme
# 请求的方式,可能性是两种,即http和https
request.path
# 请求的路径,这里是低昂对路径,如果要取绝对路径是request.get_full_path()
request.encoding
# 获取提交的数据的编码方式
request.session
# 获取是一个session,实际上就是一个无序的字符串,用来作为唯一识别吗的,因为之前我们说过http是一个无状态的协议,需要另外的东西来确保用户的状态
request.cookies
# 与session非常相似的一个东西,区别就在于session在服务端,cookies在客户端
request.method
# 获取请求方式,GET或者POST
request.body
# 请求的主体,返回数据的格式是一个字符串
request.data
# 请求的数据部分,和body相似,但是格式不同,data是一个字典对象
request.POST
# 获取POST请求所携带的数据,可以直接当成一个列表套字典来取值,但是仅仅用request.POST.get()只能取到列表的最后一位,如果要取整个列表的话需要用request.POST.getlist()来取值
request.GET
# 用法和POST几乎一样,就是获取GET()请求所携带的数据
模板的传值方式
def reg(request):
user_dict = {'name': 'jason', 'pwd': 123}
# 给模板传值的方式1
return render(request, 'reg.html', {'xxx': user_dict}) # 会将user_dict传递给reg.html页面,页面上通过xxx就能拿到该字典
# 给模板传值的方式2
return render(request, 'reg.html', locals()) # 会将当前名称空间中所有的变量名全部传递给页面
# locals()会出现效率问题,变量名很多的话,会造成空间浪费,不过个人学习的话,其实直接用locals()没什么问题
Django连接数据库及其强大的ORM
我们知道,数据库就可以当做是一个服务端,我们可以用Navicat来连接数据库,也可以直接用cmd窗口来操作数据库,同样的,我们通过Django也可以连接数据库,以及对其进行操作
Django连接数据库的前期准备
- 首先我们需要在Django的配置文件里写入要连接的数据库的信息
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql', # 指定数据库MySQL,postgreSQL
'NAME': 'db1', # 使用哪个库
'USER': 'root', # 数据库账号
'PASSWORD': 'root', # 数据库密码
'HOST': '127.0.0.1', # 数据库的地址
'PORT': 3306, # 数据库的端口
'CHARSET': 'utf8' # 数据库的默认字符编码
}
}
-
然后,Django默认使用的数据库是musqldb,然而现在这种工具几乎已经绝版了,所以我们需要告诉Django不要用mysqldb,而是用pymysql来连接数据库,这里常见的有两种方法
- 在Django的项目名下的
__init__.py
里写入下面语句 - 在Django的app名下的
__init__.py
里写入下面的语句
import pymysql pymysql.install_as_MySQLdb()
- 在Django的项目名下的
ORM语句创建表
Django里面的ORM可以帮助我们创建表,但不能直接创建数据库,所以我们要先手动创建数据库,然后通过ORM来创建表.
首先我们需要在app名下的models
里面写入需要添加进数据库的表,包括各种字段,例程如下:
from django.db import models
# Create your models here.
class Userinfo(models.Model):
# 设置id字段为Userinfo表的主键,id int primary key auto_increment
# django里面可以不指定主键字段,django的ORM会自动给当前表新建一个名为id的主键字段
id = models.AutoField(primary_key=True)
# 设置username字段, username varchar(64) CharField必须要指定max_lenth参数
# django 的ORM中,没有char字段,但是django暴露给用户可以自定义char字段
username = models.CharField(max_length=64)
# 设置password字段, password int
password = models.IntegerField()
phone = models.BigIntegerField(default=110) # 新增的字段可以提前设置默认值,如果没有提前设置,那么一定要设置可以为null,否则不让你添加字段
addr = models.CharField(max_length=64, null=True) # 该字段可以为空
class Book(models.Model):
title = models.CharField(max_length=64)
在定义好上述类之后,我们就可以通过以下两个语句来真正创建表
# 以下两个语句是在cmd窗口,或者说是在Pycharm里面的Terminal窗口里输入的,注意当前目录,一定要在项目所在的位置
python manage.py makemigrations #不会创建表,仅仅是生成一个记录,将你当前的操作记录下来(migrations文件夹)
python manage.py migrate #真正的将你的ORM语句迁移到数据库中
# 尤其要注意的是:只要在models.py中修改了跟数据库相关的代码,就必须重新开始执行上面两个语句,注意,必须重新执行!!!
ORM语句对数据库的简单操作
这里介绍最简单的两种操作,即插入和查询
数据的插入
models.Userinfo.objects.create(username='admin', password='123')
# 上述语句实现的就是这个sql语句:insert into userinfo(username,password) values('admin','123');
# create方法会有一个返回值,返回值就是当前被创建的数据对象
# 这里要注意的是,你要清楚的知道自己插入的表的字段的数量,以及格式,否则很容易报错
数据的查询
# 1. get() 当查询条件不存在的时候会直接报错,如果存在会直接给你返回数据对象本身(不推荐使用)
res = models.Userinfo.objects.get(username=username) # select * from userinfo where username = 'jason'
print(res)
print(res.username, res.password)
# 2. filter() 查询
# 当条件存在的情况下,无论数据有几条,返回的都是列表套对象的数据格式
# filter可以放多个查询条件,并且是and关系
# filter查询出来的结果当做列表去对待,支持正数的索引取值和切片,不支持负数,所以不能用[-1]
res = models.Userinfo.objects.filter(username=username, password=password)
# user_obj = res[0]
user_obj = res.first() # 取queryset第一个元素
数据的编辑
def edit_user(request):
edit_id = request.GET.get('edit_id')# 这里我们要获取前端发过来的数据中的edit_id字段,同时也是主键字段,以此为依据来取出来数据库中的该条数据
if request.method == 'POST':#如果是POST发送数据,而不是GET取数据
# 将用户新修改的所有数据
username = request.POST.get("username")
password = request.POST.get("password")
'''
POST请求中,也是可以获取GET请求携带的参数的'''
# 去数据库中修改对应的数据
# 方式一:
models.Userinfo.objects.filter(pk=edit_id).update(username=username, password=password) # 批量更新,即update方法会将filter查询出来的queryset对象中所有的数据对象全部更新
# 方式二:先获取当前数据对象,然后利用对象点属性的方式,先修改数据,然后调用对象方法保存
# 不推荐使用第二种方式,效率低,因为需要挨个重新写入数据,而不是update那种只更新有变化的
# edit_obj = models.Userinfo.objects.filter(pk=edit_id).first()
# edit_obj.username = username
# edit_obj.password = password
# edit_obj.save()
# 跳转到数据展示页面
return redirect('/userlist')
# 以edit_id为依据来取出数据库中的数据,取出的是一个对象
edit_obj = models.Userinfo.objects.filter(pk=edit_id).first()
return render(request, 'edit_user.html', locals())
数据的删除
def delete_user(request):
# 获取想要删除的数据id 直接删除
delete_id = request.GET.get('delete_id')
models.Userinfo.objects.filter(pk=delete_id).delete() # 批量删除,即filter匹配到的符合条件的数据都会删除
return redirect('/userlist')