下面所有以登录功能为例来演示这些功能css
什么是静态文件?html
网站所使用的提早写好的,后面不在进行修改的配置文件,例如前端
css文件;python
js文件;mysql
经常使用的第三方组件:sql
bootstrap数据库
sweetalertdjango
fontawesomebootstrap
如何配置静态文件后端
网站所用到的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', ]
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因为功能太多,因此不能作到面面俱到)
先去配置文件中配置相关参数
在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对应关系以下
类名 |
表名 |
---|---|
属性名 |
字段值 |
对象 |
记录 |
做用:可以让一个不会数据库操做的小白也可以经过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为主键
字段的增
能够直接在models.py中进行字段的增,可是注意有两种方式(由于数据库中可能已经存入各类数据了,新添加一个字段,那些已经有数据的字段须要进行修改)
第一种是设置默认值,例如
email = models.EmailField(default='123@qq.com')
第二种是容许新设置的字段能够为空,例如(CharField须要设置max_length)
hobby = models.CharField(null=True,max_length=32)
字段的查改删均可以经过直接操做models.py文件中的类属性
惟一须要注意的就是凡是涉及到字段的操做都须要进行数据库迁移命令,不然操做无效
查
第一步,在须要进行数据库信息查询的文件中导入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})