Django框架基础(静态文件的配置,连接数据库,Django的ROM以及字段和数据的增删改查)
下面全部以登陆功能为例来演示这些功能
一:静态文件的配置
-
什么是静态文件?
网站所使用的提前写好的,后面不在进行修改的配置文件,例如
css文件;
js文件;
常用的第三方组件:
bootstrap
sweetalert
fontawesome
-
如何配置静态文件
网站所用到的html文件统一放到templates文件夹中 那针对网站所使用到的静态文件也应该单独找一个文件夹来存储 这个文件夹 默认情况下都叫static 注意:该文件夹需要手动自己创建 并且该文件夹内部通常是以下结构 static -css 网站所用到的所有的css文件 -js 网站所用到的所有的js文件 -image 网站所用到的所有的图片文件 第三方文件
这样引入会发现无法正常引用
补充:用户在浏览器窗口之所以输入网址能够拿到对应的资源 是因为后端开设相关的资源
那如何解决找不到资源的问题呢?
-
配置django静态文件
django在配置文件中给你暴露了配置文件的配置信息 你只需要按照固定的写法书写即可暴露对应的静态文件资源
第一步:找到位置
第二步:书写配置代码
STATICFILES_DIRS = [os.path.join(BASE_DIR, 'static')]
-
如何解决动态绑定问题
什么是接口前缀,通俗的说配置中的staic就是类似一个令牌,想访问资源必须带有staic接口前缀(可以修改,但是必须与配置中的一样),只有接口前缀(令牌)相同,才会拿着后面的路径依次去配置文件夹中的STATICEFILES_DIRS中的文件夹路径下面列表中的每一个文件夹下查找对应的资源,顺序是从上往下依次查找 如果都没有找到才会报错
加入已经写好了一千个html页面,每一个页面都用了static接口前缀,然后有个需求,配置中的static接口前缀需要修改,如何快速解决将那一千个页面的接口前缀也修改了,这就需要用到接口前缀了
只需要添加下面几句代码,不论你接口前缀怎么修改,都会保持一致
{% load static %} <!--加一行这个--> <link rel="stylesheet" href="{% static 'bootstrap-3.3.7-dist/css/bootstrap.min.css' %}"> <!--在导入百分号和static即可动态绑定接口前缀--> <script src="{% static 'bootstrap-3.3.7-dist/js/bootstrap.min.js' %}"></script>
二.快速写一个简单的登陆页面
<div class="container"> <div class="row"> <div class="col-md-8 col-md-offset-2"> <h2 class="text-center">登录</h2> <form action="" method="post"> <p>username:<input type="text" name="username" class="form-control"></p> <p>password:<input type="text" name="password" class="form-control"></p> <input type="submit" class="btn btn-success "> </form> </div> </div> </div>
form表单 form表单默认是以get请求提交数据的(get请求会在url后面携带明文数据) http://127.0.0.1:8000/login/?username=admin&password=123 action 1.不写 默认朝当前地址提交数据 2.全路径 3.后缀(/index) 提交post请求的时候 需要先去配置文件中的中间件注释掉一行,因为中间件类似于保安,会检查请求和响应的数据是否安全(后面中间件有重点介绍) 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方法
1).同一个视图函数可以处理不同的请求
eg: get请求来 应该只需要返回一个html文件 post请求来 应该获取用户提交的数据 然后做进一步处理 因此必须要能够判断出当前请求到底是什么请求
request是一个对象,一个get请求就有下面这么多的方法和属性
2).method方法
总结:method可以获取前端的请求方法,并且是一个大写的GET或POST字符串
通常情况下针对不同的请求应该做不同的处理 而一般情况下get请求次数要远远多于post请求
所以我们应该针对非get请求作出逻辑判断 将get请求直接写在函数体内而不做判断
def login(request): # 要给用户返回一个登陆页面 # print('我被触发了') # 获取前端请求方式 # if request.method == 'GET': # # get逻辑 # return render(request, 'login.html') # elif request.method == 'POST': # # post逻辑 # # print(request.method,type(request.method)) # GET <class 'str'> POST <class 'str'> # # 获取数据 之后... # return HttpResponse('收到了你的数据 马上处理') """ 为了减少代码的层级:一般情况下视图函数处理get请求较多 所以可以直接再函数体内先写get请求对应的逻辑 将其他请求利用request.method做出区分 """ if request.method == 'POST': return HttpResponse('收到了') return render(request,'login.html')
3).request.POST
print(request.POST) # 获取post请求携带的数据 <QueryDict: {'username': ['admin'], 'password': ['123']}> # 可以把它当成是一个大字典 # 注意,总这些键是由前端传的name属性决定的 <p>username:<input type="text" name="username" class="form-control"></p> # 若没有name属性,即时在前端input框内提交了数据,也不会朝后端发送这个数据
因此:在input框中一定要有name属性
4).如何获取post里面的数据(get和getlist)
# 例如:在前端页面中有以下三个input框需要输入数据传入后端 <p>username:<input type="text" name="username" class="form-control"></p> <p>username:<input type="text" name="username" class="form-control"></p> # 并且有两个相同的name属性 <p>password:<input type="text" name="password" class="form-control"></p> # 可通过get的方式 print(request.POST) username = request.POST.get('usernamr') password = request.POST.get('password') print(username, type(usernsme)) print(password, type(password)) ''' <QueryDict: {'username': ['admin', 'jason'], 'password': ['123']}> jason <class 'str'> 123 <class 'str'> ''' #相同的name属性得到的是一个字典套集合的形式, # 通过结果我们可以发现数据都是字符串,如果数据是一个列表,那么get获取数据只能只是列表最后一个数据,不能全部获取 username = request.POST.getlist('usernamr') # 通过getlist的方式可以获取整个列表
5)如何获取GET请求的数据
GET请求和POST请求是一样的,只不过GET请求获取的是url后面携带的数据:url?xxx=xxx&yyy=yyy # 获取符合get请求携带参数特点的数据 url?xxx=xxx&yyy=yyy print(request.GET) # <QueryDict: {'username': ['admin'], 'password': ['123']}> print(request.GET.get('username'),type(request.GET.get('username'))) # admin <class ’str‘> print(request.GET.getlist('password'),type(request.GET.getlist('password'))) # ['123'] <class 'list'> 只要符合这个url?xxx=xxx&yyy=yyy格式,request.GET都能获取数据
四.链接数据库
-
先找到database
-
找到对应的数据库
-
下载驱动尝试链接数据库
-
链接成功后就能找到数据库表了
-
一些简单操作(注意:pycharm由于功能太多,所以不能做到面面俱到)
五.Django链接数据库
-
先去配置文件中配置相关参数
在settings中找到下面这个配置信息,进行修改
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql', # 数据库类别
'NAME': 'day49', # 库的名字
'HOST': '127.0.0.1',
'PORT': 3306,
'USER': 'root',
'PASSWORD': '123',
'CHARSET': 'utf8'
}
}
下面的错误表示Djiango使用的是mysqldb这个模块,这个版本是不兼容的,需要切换成pymysql模块
-
在项目名或者应用名下面的__ init __.py文件中告诉django使用pymysql链接数据库而不是用默认的mysqldb
import pymysql pymysql.install_as_MYSQLdb()
六.django中的ORM
注意:django不能自动创建库,需要自己手动创建,但是可以自动创建表
orm对应关系如下
类名 |
表名 |
---|---|
属性名 |
字段值 |
对象 |
记录 |
作用:能够让一个不会数据库操作的小白也能够通过Python面向对象语法 句点符来简单快捷的操作数据
-
首先需要先去对应的应用下的models.py中书写你的模型类
class User(models.Model): # id int primary key auto_increment id = models.AutoField(primary_key=True) # name varchar(32) name = models.CharField(max_length=32) # password int password = models.IntegerField()
-
执行数据库迁移命令(就是将models.py中建立的类同步到数据库中)
1.python3 manage.py makemigrations # 仅仅是将你对数据库的改动记录到某个小本本上(migrations文件夹) 2.python3 manage.py migrate # 将改动真正的同步到数据库中
-
执行第一步会产生下面的效果
-
执行第二步之后
补充知识点:
-
快捷命令输入
-
如果主键名为id,可以不设置,django默认设置主键,如果设置了,以自定义的id为主键
七.如何在django中进行数据库字段的增删改查
-
字段的增
可以直接在models.py中进行字段的增,但是注意有两种方式(因为数据库中可能已经存入各种数据了,新添加一个字段,那些已经有数据的字段需要进行修改)
第一种是设置默认值,例如
email = models.EmailField(default='123@qq.com')
第二种是允许新设置的字段可以为空,例如(CharField需要设置max_length)
hobby = models.CharField(null=True,max_length=32)
-
字段的查改删都可以通过直接操作models.py文件中的类属性
唯一需要注意的就是凡是涉及到字段的操作都需要进行数据库迁移命令,否则操作无效
八.如何在django中进行数据库记录的增删改查
-
查
第一步,在需要进行数据库信息查询的文件中导入models文件
from app01 import models
第二步,通过filter的方法可以拿到所需要的数据列表
res = models.User.objects.filter(name=username) # 该方法返回的结果你可以看成是一个列表套数据对象的形式,其中User表示表名,name表示字段名,后一个username是前端返回来的数据,即查询条件 print(res) # <QuerySet [<User: User object>]>
第三步,该数据列表支持索引取值
user_obj = res[0] # QuerySet支持索引取值但是不支持负数 并且也不推荐直接索引取值 user_obj = res.first() # 索引和first()这两种方法都可以 # print(user_obj.name,user_obj.password)
补充:当查询条件不存在的时候,是一个queryset[]空列表,不会报错
filter括号内直接放多个关键字参数 并且多个关键字参数之间是and关系 res = models.User.objects.filter(username='jason',password='123') # select * from user where username='jason' and password='123';
-
查所有数据
1.filter() 括号内不写拿所有 <QuerySet [<User: jason>, <User: egon>, <User: sean>, <User: admin>]> 2.all() 查询所有数据 <QuerySet [<User: jason>, <User: egon>, <User: sean>, <User: admin>]>
-
增
1.create() user_obj = models.User.objects.create(name=username,password=password) print(user_obj,user_obj.name) # 该方法有返回值 返回值就是当前被创建的对象本身 2.对象的绑定方法 # 1 先生成一个User对象 user_obj = models.User(name=username,password=password) # 2 调用对象的绑定方法 user_obj.save()
-
删
# 简单的删除逻辑 # 用户通过点击删除键就能删除数据,需要获取指定数据的id,通过这个id来操作数据的删除 第一步:在前端删除键上可以绑定数据的id,这样发送get请求就会带上id <a href="/delete_user/?delete_id={{ user_obj.id }}" class="btn btn-danger btn-xs">删除</a> 第二步:后端通过id来获取数据 def del_user(request): # 如何获取用户想逃删除的数据id delete_id = request.GET.get("delete_id") # 直接根据id删除数据 models.User.objects.filter(id=delete_id).delete() # 将filter过滤出来的数据全部删除 # 重定向到展示页 return redirect('/home/')
-
改
改和删前面基本一致 后面有两种方法 def edit_user(request): # 获取用户想要修改的数据id值 edit_id = request.GET.get('edit_id') if request.method == 'POST': # 获取用户修改之后的用户名和密码 username = request.POST.get('username') password = request.POST.get('password') # 修改数据 # 方式1(推荐) # models.User.objects.filter(id=edit_id).update(name=username,password=password) # 方式2(了解) # 1 先获取数据对象 edit_obj = models.User.objects.filter(id=edit_id).first() # 2 再修改对象属性 edit_obj.name = username edit_obj.password = password # 3 调用对象的绑定方法保存 edit_obj.save() # 再次跳转到数据展示页 return redirect('/home/') # 根据id获取数据对象 并且展示到html页面上 edit_obj = models.User.objects.filter(id=edit_id).first() return render(request,'edit_user.html',{'edit_obj':edit_obj})