静态文件配置
所有的html文件默认都写在templates文件夹下
所有的静态文件(css,js,前端第三方类库)默认都放在static文件夹下
html页面引入外部资源的方式:cdn、本地
静态文件配置
STATIC_URL:
和静态文件夹的名字没有关系
默认情况下这个前缀跟静态文件夹名字一样!!!
html文件head导入的本地数据,以此前缀开头,否则无法实现相应的效果
STATICFILES_DIRS:
暴露给外界能够访问服务器静态文件夹下面所有的资源
会依次查找列表中所有的静态文件路径,找到立刻停止,都没有找到返回404
STATIC_URL = '/static/' # 接口前缀# 静态文件配置 STATICFILES_DIRS = [ os.path.join(BASE_DIR,'static') # 静态文件夹路径 os.path.join(BASE_DIR,'static1'), ]
登录功能
1. 路由访问
路由访问如果不加斜杠,会内部自动重定向加斜杠的路由
form表单触发提交数据的动作两种方式:
<input type="submit"> <button></button>
2. form表单
1)form提交数据的地址如何指定及方式?
action属性控制提交地址的方式:
1.全路径 <form action="http://127.0.0.1:8000/login/"> 2.只写路径后缀 <form action="/login/"> 3.不写 (默认往当前路径提交)
2)form表单默认提交方式:get请求
若将from表单的 method='post',运行时出现以下页面:
将settings文件内的该中间键注释掉即可:
3. 后端数据处理
根据客户端请求方式的不同执行不同的逻辑代码
获取用户端提交方式:request.method
当提交方式为 POST:request.POST 得到的结果,类似于一个字典里存放了客户端post提交的所有数据
获取请求方式的两种表达方式:
def login(request): # 获取用户端提交的请求方式 print(request.method) # 默认得到的请求方式是全大写的字符串 if request.method == 'GET': return render(request, 'login.html') elif request.method == 'POST': return HttpResponse("收到了")
def login(request): if request.method == 'POST': return HttpResponse("OK") return render(request, 'login.html')
request.POST 的取值方式:
def login(request): if request.method == 'POST': print(request.POST) # <QueryDict: {'username': ['Tom'], 'password': ['123']}> print(request.POST.get('username')) # Tom, value虽然是个列表,但是默认获取到value列表的最后一个元素 print(request.POST.getlist('username')) # ['Tom', 'Bob'] 要想一次性获取value列表里面所有的数据需要用getlist()(多个爱好) print(request.POST['password']) # 123 不推荐使用该方法,取不到时会报错 return HttpResponse("OK") return render(request, 'login.html')
request.GET 的取值方式和request.POST 完一样
4. 基于pymysql完成登录功能
from django.shortcuts import render, HttpResponse, redirect import pymysql def login(request): if request.method == 'POST': username = request.POST.get('username') password = request.POST.get('password') conn = pymysql.connect( host='127.0.0.1', port=3306, user='root', database='initial', password='123', charset='utf8', autocommit=True ) cursor = conn.cursor(pymysql.cursors.DictCursor) cursor.execute('select * from user where name=%s and password=%s', (username, password)) userinfo = cursor.fetchall() if userinfo: return HttpResponse('登录成功!') return render(request, 'login.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 rel="stylesheet" href="/static/bootstrap-3.3.7/css/bootstrap.min.css"> <script src="/static/bootstrap-3.3.7/js/bootstrap.min.js"></script> </head> <body> <div class="container"> <div class="row"> <h1>登录页面</h1> <div class="col-md-4 col-md-offset-4"> <form action="/login/" method="post"> <p>username: <input type="text" class="form-control" name="username"></p> <p>password: <input type="text" class="form-control" name="password"></p> <input type="submit"> </form> </div> </div> </div> </body> </html>
django连接数据库
django默认自带一个小型数据库:sqlite3,可以用来做本地测试
1. 连接MySQL,修改配置文件:键必须大写
2. 告诉django 用pymysql 替换默认的db.sqlite3,连接数据库:
方式1:项目文件夹下__init__.py
方式2:应用文件夹下__init__.py
import pymysql
pymysql.install_as_MySQLdb() # 告诉django用pymsql代替db.sqlite3连接数据库
django 的 orm
1. 关于django的orm
不能创建库,但是可以创建表
注意:一个django项目使用一个库
创建的表的表名:“app应用名_”作为前缀名,避免多个app应用的表重名
数据库迁移(同步)命令******
1. 命令1:在应用下migrations中,自动生成迁移记录"编号_库名.py"
2. 命令2:在数据库中生成表"应用名_表名",及django运行时需要用到相应表
eg:django_session记录用户的登录记录....
python3 manage.py makemigrations # 数据库变动记录(并不会创建表)
python3 manage.py migrate # 将数据变动同步到数据库中
1)app01 > models.py 创建表 > 类
from django.db import models class User(models.Model): id = models.AutoField(primary_key=True) # 设置为主键字段 name = models.CharField(max_length=32) # CharField定义时必须加max_length参数 password = models.CharField(max_length=32)
2)在Terminal中使用数据库迁移命令
只要修改了模型层里面的跟表相关的所有的数据,就必须重新执行数据库迁移命令
注意:添加新字段,需设置default值
from __future__ import unicode_literals from django.db import migrations, models class Migration(migrations.Migration): initial = True dependencies = [ ] operations = [ migrations.CreateModel( name='User', fields=[ ('id', models.AutoField(primary_key=True, serialize=False)), ('name', models.CharField(max_length=32)), ('password', models.CharField(max_length=32)), ], ), ]
2.django 版本注册功能
先将注册函数?添加到urls.py的urlpatterns列表中:
url(r'^reg/', views.reg),
新增数据
def reg(request): if request.method == 'POST': username = request.POST.get('username') # 获取用户输入的用户名 password = request.POST.get('password') # 操作数据库user表插入数据 # 方式1: # user_obj = models.User.objects.create(name=username, password=password) # 方式2: user_obj = models.User(name=username, password=password) user_obj.save() # 对象调用save方法保存到数据库 print(user_obj.pk) # pk获取主键字段对应的值 不管主键叫什么名字 print(user_obj.name) # 获取用户输入的name print(user_obj.password) # 获取用户输入的password return HttpResponse("注册成功") return render(request, 'reg.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 rel="stylesheet" href="/static/bootstrap-3.3.7/css/bootstrap.min.css"> <script src="/static/bootstrap-3.3.7/js/bootstrap.min.js"></script> </head> <body> <div class="container"> <div class="row"> <h1>注册页面</h1> <div class="col-md-4 col-md-offset-4"> <form action="" method="post"> <p>username:<input type="text" name="username" class="form-control"></p> <p>password:<input type="password" name="password" class="form-control"></p> <input type="submit" class="btn btn-success"> </form> </div> </div> </div> </body> </html>
3. orm 查询数据库信息
注意:只要是QuerySet对象,就可以.query查看获取它的内部sql语句
先将注册函数?添加到urls.py的urlpatterns列表中:
url(r'^userlist/', views.userlist),
查询数据
def userlist(request): # 获取数据库数据 user_list = models.User.objects.all() # 获取user表所有的数据 print(user_list.query) # select * from user;得到select语句相关内容 for user_obj in user_list: print(user_obj.pk, user_obj.name) # 得到id name return render(request, "userlist.html", locals())
4. orm编辑删除数据
1)a标签的href属性
可以指定页面跳转的路径:可以写全路径,但推荐写后缀
注意:路径的书写一定要加斜杠,不然会在地址栏出叠加而无法跳转
2)QuerySet对象
一个存放数据对象的列表的集合,可为空<QuerySet []> <class 'django.db.models.query.QuerySet'>
? 可以获取QuerySet对象的操作:
models.User.objects.all() User表的所有数据
models.User.objects.filter(**kwargs) 符合filter条件的数据
? QuerySet 对象的方法:
.query 查看内部sql语句的功能
.first() 获取第一个数据对象,无值返回None
.delete() 删除所有数据对象
.update(**kwargs) 修改所有数据对象的属性
[number] 支持索引取值,但无值会报错
? 注意:QuerySet对象 & models.User.objects.get(**kwargs)
get可以直接获取到数据对象本身,但是查询条件不存在的情况下直接报错
数据对象的修改:
user_obj = models.User.objects.filter(id=edit_id).first()
user_obj.name = username
user_obj.save()
3)编辑对象的id
获取方式1:利用input隐藏一个标签
获取方式2:以get方式携带参数
方式1: <input type="hidden" name="edit_id" value="{{ user_obj.pk }}"> 方式2: <form action="/edit/?edit_id={{ user_obj.pk }}" method="post">
删改数据
<!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 rel="stylesheet" href="/static/bootstrap-3.3.7/css/bootstrap.min.css"> <script src="/static/bootstrap-3.3.7/js/bootstrap.min.js"></script> </head> <body> <div class="container"> <div class="row"> <h1>展示数据</h1> <div class="col-md-8 col-md-offset-2"> <a href="/reg/" class="btn btn-success">添加数据</a> <table class="table-hover table table-bordered table-striped"> <thead> <tr> <th>id</th> <th>name</th> <th>password</th> <th>action</th> </tr> </thead> <tbody> {% for user_obj in user_list %} {# user_list = [obj1,obj2,obj3] #} <tr> <td>{{ user_obj.pk }}</td> <td>{{ user_obj.name }}</td> <td>{{ user_obj.password }}</td> <td> <a href="/edit/?edit_id={{ user_obj.pk }}" class="btn btn-primary">编辑</a> <a href="/delete_user/?delete_id={{ user_obj.pk }}" class="btn btn-danger">删除</a> </td> </tr> {% endfor %} </tbody> </table> </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 rel="stylesheet" href="/static/bootstrap-3.3.7/css/bootstrap.min.css"> <script src="/static/bootstrap-3.3.7/js/bootstrap.min.js"></script> </head> <body> <div class="container"> <div class="row"> <h1>编辑数据</h1> <div class="col-md-6 col-md-offset-3"> <form action="/edit/?edit_id={{ user_obj.pk }}" method="post"> <input type="hidden" name="edit_id" value="{{ user_obj.pk }}"> <p>username:<input type="text" name="username" value="{{ user_obj.name }}" class="form-control"></p> <p>password:<input type="password" name="password" value="{{ user_obj.password }}" class="form-control"></p> <input type="submit" class="btn btn-warning"> </form> </div> </div> </div> </body> </html>
def delete_user(request): delete_id = request.GET.get('delete_id') models.User.objects.filter(id=delete_id).delete() return redirect('/userlist/') def edit(request): if request.method == 'POST': username = request.POST.get('username') password = request.POST.get('password') edit_id = request.POST.get('edit_id') # 获取id的方式,由edit.html页面的提交方式决定 edit_id = request.GET.get('edit_id') # 更新数据库 models.User.objects.filter(id=edit_id).update(name=username, password=password) return redirect('/userlist/') edit_id = request.GET.get('edit_id') # 获取要修改的数据id # 将查到的数据渲染到一个编辑数据 # 查询数据方式1: user_obj = models.User.objects.filter(id=edit_id).first() # 查询数据方式2:不推荐 # user_obj = models.User.objects.get(id=edit_id) return render(request, "edit.html", locals())