利用Django去操作数据库并完成简易的登录及编辑功能
一、静态文件
什么是静态文件?
简单来说静态文件就是已经提前写好了的,可以给网站使用的文件
比如:
css
js
第三方的一些组件:如bootstrap, sweetalter ,fontawesome等
现在我们已经知道了网站所使用的HTML文件要存放到templates文件夹中,那么同理针对网站所使用
到的静态文件也用该单独找哟个文件夹来存储,这个文件夹默认情况下就都叫static
该文件夹内部通常都是以下的结构
static
- css
网站所使用的所有的css文件
- js
网站所有用到的js文件
- image
网站所有用到的图片的文件
- 第三方文件
二、Django静态文件配置
Django在配置文件中给你提供了配置文件的一些信息 我们只需要按照固定的写法书写
1、新建一个static文件
2、将我们新建好的静态文件添加到配置文件中去
3、添加好了静态文件的配置以后我们就可以使用静态文件的功能了(这里我用的是bootstrap的静态文件)
基本配置:
STATIC_URL = '/static/' # 这里的static是访问后端静态资源的接口前缀 默认情况下接口前缀名与静态文件名保持一致
"""
<link rel="stylesheet" href="/xxx/bootstrap-3.3.7-dist/css/bootstrap.min.css">
你要想访问后端的静态资源 你必须以接口前缀开头 后面跟上具体的文件路径 才能够访问到对应的资源
当你的接口前缀正确之后 会拿着后面的路径依次去下面列表中的每一个文件夹下查找对应的资源
顺序是从上往下依次查找 如果都没有找到才会报错
STATICFILES_DIRS = [
os.path.join(BASE_DIR,'static'), # 这里的static才是你文件夹的路径
os.path.join(BASE_DIR,'static1'),
os.path.join(BASE_DIR,'static2'),
]
解决动态绑定问题(*******)
{% load static %}
<link rel="stylesheet" href="{% static 'bootstrap-3.3.7-dist/css/bootstrap.min.css' %}">
<script src="{% static 'bootstrap-3.3.7-dist/js/bootstrap.min.js' %}"></script>
三、form表单
form表单默认是以get请求提交数据的
http://127.0.0.1:8000/login/?username=admin&password=123
action
1.不写 默认朝当前地址提交数据
2.全路径
3.后缀(/index)
提交post请求的时候 需要先去配置文件中注释掉一行
如下图将settings下的这一行注释掉
视图函数应该做到针对不同的请求 做出不同的处理逻辑
eg:
get请求来 应该只需要返回一个html文件
post请求来 应该获取用户提交的数据 然后做进一步处理
你必须要能够判断出当前请求到底是什么请求
四、request对象
获取前端请求方式
request.method # 结果是一个纯大写的字符串 GET/POST
request.POST # 获取post请求提交的数据 类似于是一个大字典
# <QueryDict: {'username': ['admin', 'jason'], 'password': ['123']}>
request.POST.get() # 只会取列表最后一个元素
request.POST.getlist() # 取出整个列表
request.GET # 获取符合get请求携带数据格式的数据 url?xxx=yyy&ooo=lll
# <QueryDict: {'username': ['admin', 'jason'], 'password': ['123']}>
request.GET.get() # 只会取列表最后一个元素
request.GET.getlist() # 取出整个列表
通常情况下针对不同的请求应该做不同的处理 而一般情况下get请求次数要远远多于post请求
所以我们应该针对非get请求作出逻辑判断 将get请求直接写在函数体内而不做判断
五、pycharm连接数据库
1、准备工作:
将settings中默认的数据库换成我们自己的数据库
两种方式
方式一:
方式二:
六、Django连接数据库(******)
需要你自己提前创建好对应的库
·
1.先去配置文件中配置相关参数(注意default中的参数一定要全部大写)
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql', # 数据库类别
'NAME': 'day49', # 库的名字
'HOST':'127.0.0.1',
'PORT':3306,
'USER':'root',
'PASSWORD':'123',
'CHARSET':'utf8'
}
}
2.在项目名或者应用名下面的__init__文件中告诉django使用pymysql链接数据库而不是用默认的mysqldb
import pymysql
pymysql.install_as_MySQLdb()
七、Django orm简介
django orm不会帮你创建库 只能帮你自动创建表
orm对象关系映射
类 表
对象 记录
属性 字段值
作用:能够让一个不会数据库操作的小白也能够通过Python面向对象语法 句点符来简单快捷的操作数据
首先需要先去对应的应用下的models.py中书写你的模型类
比如:
from django.db import models # Create your models here. class User(models.Model): # 等价于 id int primary_key auto_increment id = models.AutoField(primary_key=True) # 注:在Django中id可以不用自己创建 ,但如果主键名字不是id那就得自己创建了 name = models.CharField(max_length=64) # 等价于 name varchar(64) 注意:这个max_length=一定要添加,不然会报错 # 并且CharField其实表示的StringField,这个名字和之前的orm有点不一样 password = models.CharField(max_length=32) def __str__(self): return self.name class Book(models.Model): name = models.CharField(max_length=32)
注意(*********************一定要注意*********************):
(一、terminal命令行)
这里有个特别需要注意的点:一旦你修改了和数据库内容相关的字段或字段值,一定要把下面两行代码加上
1、python manage.py makemigrations(这一步仅仅只是将你对数据库的改动记录到一个文件下这个文件就是migrations文件)
2、python manage.py migrate # 这一步才是将改动过的数据真正的同步到数据库中
注意: 上面的两行命令永远是成对出现的 只要你执行了1 那么就必须要执行2
*******只要你动了models.py跟数据相关的代码 你就必须要重新执行上面的两条命令来保证数据库与models.py一致*******
(二、快捷键智能提示)
八、字段的增删查改
字段的增
1.要么给该字段设置默认值
2.要么运行该字段可以为空
字段的查
...
字段的改
修改models代码 之后执行数据库迁移命令即可
字段的删
只要注释掉对应的字段 执行数据库迁移命令就会将对应的字段及数据信息全部删除(慎用)
例如:
九、数据库的增删查改
查
1.filter()
from app01 import models
res = models.User.objects.filter(username='jason') # select * from user where username='jason'
# 返回的结果是一个列表 支持索引取值但是不支持负数并且不推荐使用 推荐你使用它给你封装好的方法
user_obj = res.first()
# filter方法条件不存在的时候 不会报错返回的是一个空列表
"""
filter括号内直接放多个关键字参数 并且多个关键字参数之间是and关系
res = models.User.objects.filter(username='jason',password='123') # select * from user where username='jason' and password='123';
"""
2.查所有的数据
1.filter() 括号内不写拿所有
<QuerySet [<User: jason>, <User: egon>, <User: sean>, <User: admin>, <User: 你不行>]>
2.all() 查询所有数据
<QuerySet [<User: jason>, <User: egon>, <User: sean>, <User: admin>, <User: 你不行>]>
增
1.create()
user_obj = models.User.objects.create(name=username,password=password)
print(user_obj,user_obj.name)
# 该方法有返回值 返回值就是当前被创建的对象本身
2.对象的绑定方法
# 方式2
# 1 先生成一个User对象
user_obj = models.User(name=username,password=password)
# 2 调用对象的绑定方法
user_obj.save()
删
用户点击谁 你的后端就应该删除
后端如何获取用户想要删除的数据id?
models.User.objects.filter(id=delete_id).delete() # 将filter过滤出来的数据全部删除 批量删除
改
如何获取用户想要修改的数据id
根据数据id获取数据并且展示到前端页面供用户查看
# 方式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()
"""mylogin URL Configuration The `urlpatterns` list routes URLs to views. For more information please see: https://docs.djangoproject.com/en/1.11/topics/http/urls/ Examples: Function views 1. Add an import: from my_app import views 2. Add a URL to urlpatterns: url(r'^$', views.home, name='home') Class-based views 1. Add an import: from other_app.views import Home 2. Add a URL to urlpatterns: url(r'^$', Home.as_view(), name='home') Including another URLconf 1. Import the include() function: from django.conf.urls import url, include 2. Add a URL to urlpatterns: url(r'^blog/', include('blog.urls')) """ from django.conf.urls import url from django.contrib import admin from app01 import views urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^login/', views.login), url(r'^reg/', views.reg), # 用户展示页 url(r'^home/', views.home), # 删除功能 url(r'^delete_user/', views.del_user), # 编辑功能 url(r'^edit_user/', views.edit_user) ]
from django.shortcuts import render, HttpResponse, redirect from app01 import models # Create your views here. def login(request): # 要给用户返回一个登录页面 '''为了减少代码的层级:一般情况下视图函数处理的get请求较多 所以可以直接在函数体内先写get请求对应的逻辑 再将其他请求利用request.method做出区分 ''' if request.method == 'POST': # 如何获取数据(get和post) # print(request.GET) # print(request.POST) # 获取post请求携带的数据 <QueryDict: {'username': ['admin'], 'password': ['123']}>你就把它当成是一个大字典即可 # 获取用户的用户名以及密码 # username = request.POST.get('username') # get只会默认取列表中的最后一个元素 # password = request.POST.get('password') # print(username, type(username)) #yaya <class 'str'> # print(password, type(password)) #123 <class 'str'> # # 如果你想要直接拿到列表 # username = request.POST.getlist('username') # print(username, type(username)) #['yaya'] <class 'list'> username = request.POST.get('username') password = request.POST.get('password') # 查询数据库 res = models.User.objects.filter(name=username) # 该方法返回的结果你可以看出是一个列表套数据对象的形式,filter相当于SQL语句的where # print(res) #<QuerySet [<User: yafeng>]> # user_obj = res[0] #QuerySet支持索引取值 但是不支持负数 并且虽然支持索引取值但是并不推荐你直接索引取值 # user_obj = res.first() # 推荐使用这种方式去获取对象 # print(user_obj.name, user_obj.password) if res: user_obj = res.first() if user_obj.password == password: return HttpResponse('登录成功') else: return HttpResponse('密码错误') return HttpResponse('用户名不存在') # 获取符合get请求携带参数特点的数据 url?xxx=xxx&yyy=yyy # print(request.GET) # <QueryDict: {'username': ['admin'], 'password': ['123']}> # print(request.GET.get('username'),type(request.GET.get('username'))) # print(request.GET.getlist('password'),type(request.GET.getlist('password'))) return render(request, 'login.html') def reg(request): if request.method == 'POST': username = request.POST.get('username') password = request.POST.get('password') # 直接超数据卡中添加数据 # 方式一(推荐使用) user_obj = models.User.objects.create(name=username, password=password) print(user_obj, user_obj.name) # # 方式二 # # 1、先生成一个use对象 # user_obj = models.User(name=username, password=password) # # 2、调用对象的绑定方法 # user_obj.save() return render(request, 'register.html') def home(request): # 获取user表中的所有数据 res = models.User.objects.filter() # 不给参数相当于查所有 # print(res) user_queryset = models.User.objects.all() #查所有数据 return render(request, 'home.html', {'res': user_queryset}) 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') # 修改数据 # # 方式一(推荐) # models.User.objects.filter(id=edit_id).update(name=username, password=password) # 方式二 # 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})
from django.db import models # Create your models here. class User(models.Model): # 等价于 id int primary_key auto_increment id = models.AutoField(primary_key=True) # 注:在Django中id可以不用自己创建 ,但如果主键名字不是id那就得自己创建了 name = models.CharField(max_length=64) # 等价于 name varchar(64) 注意:这个max_length=一定要添加,不然会报错 # 并且CharField其实表示的StringField,这个名字和之前的orm有点不一样 password = models.CharField(max_length=32) def __str__(self): return self.name class Book(models.Model): name = models.CharField(max_length=32) # price = models.CharField(max_length=11)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script> {# <link href="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">#} {# <script src="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>#} {% load static %} <link rel="stylesheet" href="{% static 'bootstrap-3.3.7-dist/css/bootstrap.min.css' %}"> <script src="{% static 'bootstrap-3.3.7-dist/js/bootstrap.min.js' %}"></script> </head> <body> <div class="container"> <div class="row"> <div class="col-md-8 col-md-offset-2"> <h2 class="text-center">登录</h2> <form action="" method="post"> <!--将请求方式改成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> </body> </html>
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script> {# <link href="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">#} {# <script src="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>#} {% load static %} <link rel="stylesheet" href="{% static 'bootstrap-3.3.7-dist/css/bootstrap.min.css' %}"> <script src="{% static 'bootstrap-3.3.7-dist/js/bootstrap.min.js' %}"></script> </head> <body> <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-primary"> </form> </div> </div> </div> </body> </html>
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script> {# <link href="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">#} {# <script src="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>#} {% load static %} <link rel="stylesheet" href="{% static 'bootstrap-3.3.7-dist/css/bootstrap.min.css' %}"> <script src="{% static 'bootstrap-3.3.7-dist/js/bootstrap.min.js' %}"></script> </head> <body> <div class="container"> <div class="row"> <div class="col-md-8 col-md-offset-2"> <h2 class="text-center">编辑</h2> <form action="" method="post"> <!--将请求方式改成post--> <p>username:<input type="text" name="username" class="form-control" value="{{ edit_obj.name }}"></p> <p>password:<input type="text" name="password" class="form-control" value="{{ edit_obj.password }}"></p> <input type="submit" class="btn btn-warning pull-right"> </form> </div> </div> </div> </body> </html>
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script> {# <link href="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">#} {# <script src="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>#} {% load static %} <link rel="stylesheet" href="{% static 'bootstrap-3.3.7-dist/css/bootstrap.min.css' %}"> <script src="{% static 'bootstrap-3.3.7-dist/js/bootstrap.min.js' %}"></script> </head> <body> <div class="container"> <div class="row"> <div class="col-md-8 col-md-offset-2"> <h1 class="text-center">数据展示</h1> <table class="table table-striped table-hover"> <thead> <tr> <th>id</th> <th>name</th> <th>password</th> <th>operation</th> </tr> </thead> <tbody> {% for user_obj in res %} <!--[user_obj1, user_obj2...]--> <tr> <td>{{ user_obj.id }}</td> <td>{{ user_obj.name }}</td> <td>{{ user_obj.password }}</td> <td> <a href="/edit_user/?edit_id={{ user_obj.id }}" class="btn btn-primary btn-xs">编辑</a> <a href="/delete_user/?delete_id={{ user_obj.id }}" class="btn btn-danger btn-xs">删除</a> <!--这个是查找具有delete_user的路由然后到对应的视图函数,并在请求的同时将用户的数据一并提交--> </td> </tr> {% endfor %} </tbody> </table> </div> </div> </div> </body> </html>
效果图:
查询数据:
删除:
修改:
增加: