初识Django
前言
1. 浏览器往服务端发的叫 请求(request) 请求的消息格式: 请求方法 路径 HTTP/1.1\r\n k1:v1\r\n k2:v2\r\n \r\n 请求数据 2. 服务端往浏览器发的叫 响应(response) 响应的消息格式: HTTP/1.1 状态码 状态描述符\r\n k1:v1\r\n k2:v2\r\n \r\n 响应正文 <-- html的内容
动态的网页: 本质上都是字符串的替换 字符串替换发生在什么地方: 在服务端替换完再返回给浏览器!!! 总结一下: 1. web框架的本质: socket服务端 与 浏览器的通信 2. socket服务端功能划分: a. 负责与浏览器收发消息(socket通信) --> wsgiref/uWsgi/gunicorn... b. 根据用户访问不同的路径执行不同的函数 c. 从HTML读取出内容,并且完成字符串的替换 --> jinja2(模板语言) 3. Python中 Web框架的分类: 1. 按上面三个功能划分: 1. 框架自带a,b,c --> Tornado 2. 框架自带b和c,使用第三方的a --> Django 3. 框架自带b,使用第三方的a和c --> Flask 2. 按另一个维度来划分: 1. Django --> 大而全(你做一个网站能用到的它都有) 2. 其他 --> Flask 轻量级
一个完整得请求流程: 0. 启动服务端,等待客户端(用户的浏览器)来连接 1. 在浏览器地址栏输入URL,与服务端建立连接,浏览器发送请求 2. 服务端收到请求消息,解析请求消息,根据路径和函数的对应关系,找到将要执行的函数 3. 执行函数,打开HTML文件,进行字符串替换,得到一个最终要返回的HTML内容 4. 按照HTTP协议的消息格式要求,把HTML内容回复给用户浏览器(发送响应) 5. 浏览器收到响应的消息之后,按照HTML的规则渲染页面. 6. 关闭连接
一、django介绍
①启用django注意事项(*****): 计算机的名称不能有中文 一个pycharm就是一个项目 项目名不能起中文 ②下载: 推荐下载1.11.11版本 两种下载方式: 命令行直接下载:pip3 install django==1.11.11 pycharm下载 验证下载是否成功: cmd --> django-admin ③创建django项目的两种方式: 方式一:命令行创建 创建django项目:cmd -> D: -> django-admin startproject 项目名 创建app应用: cd 项目名 -> python3 manage.py startapp app01 启动django项目:python3 manage.py runserver ps:用命令行创建django默认不会自动创建templates文件夹 需要你手动自己创建(注意改文件夹路径是否被添加配置文件中) 方式二:pycharm创建 创建django项目:file >>> new project 选择第二个django ps:需要注意名字不能有中文,选择本地的解释器,勾选后台管理 创建app:方式一:pycharm命令行创建 -> python3 manage.py startapp app01 方式二:Tools下面run manage.py task功能栏 -> startapp app01 启动diango项目:点击小绿色箭头,直接可以启动Django项目(前提是小三角左边是你的Django项目) 强调:1.用django一定要保证只有一个在运行状态 2.一定记得清浏览器的缓存
新建django项目时--配置相关 项目名/settings.py文件
1. Templates(存放HTML文件的配置) <-- 告诉Django去哪儿找我的HTML文件
2. 静态文件(css/js/图片)
# 静态文件保存目录的别名
STATIC_URL = '/static/'
# 所有静态文件(css/js/图片)都放在我下面你配置的文件夹中
STATICFILES_DIRS = [
os.path.join(BASE_DIR, "static"),
]
3. 注释掉setting.py中 带有 csrf 的那一行(大概45~47行)
④app应用概念: 一个django项目就是一所大学 app就是大学里面的学院 注意:新创建的app需要在配置文件中注册才能生效(*****) INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'app01.apps.App01Config' # 可以用全称,推荐此方法 # 也可以简写成‘app01' ]
二、Django各个文件的作用
二、form用get和post提交数据
1. GET请求和POST请求
都属于HTTP协议规定的请求方法
2. 什么时候用GET请求?
1. 浏览器想要得到一个HTML页面的时候
2. 搜索引擎查询关键字的时候 www.sogo.com/web/?query=迪丽热巴
3. 什么时候用POST?
1. 向后端提交数据
1. 大段的数据
2. 包含隐私的数据
3. 上传文件
4. 实际中GET和POST的应用场景
1. GET:
1. 直接在浏览器地址栏输入URL访问网站
2. a标签
2. POST:
1. 登录注册
2. 修改(新增)大段的数据
3. 上传文件
form提交数据的地址指定的三种方式:
action属性控制提交的地址 方式: 1.全路径 <form action="http://127.0.0.1:8000/login/"> 2.只写路径后缀 <form action="/login/"> 3.不写 (默认往当前路径提交) form表单默认是get请求
def login(request): # 获取用户端提交的请求方式 print(request.method) # 拿到的请求方式是全大写的字符串 if request.method == 'POST': print(request.POST) # 你就把它当成一个大字典里面存放了客户端post提交的所有的数据 # request.POST:< QueryDict: {'username': ['jason'], 'password': ['123']} > print(request.POST.get('username')) # value虽然是个列表但是获取value的时候拿到却是单个元素 # 默认只会取value列表里面的最后一个元素 # request.POST:<QueryDict: {'username': ['jason', 'egon'], 'password': ['123']}> print(request.POST.getlist('username')) # 要想一次性获取value列表里面所有的数据需要用getlist() # ['jason', 'egon'] print(request.POST['password']) # 不推荐使用该方法获取数据 return HttpResponse('OK') return render(request,'login.html') # 获取value列表里面所有的元素需要使用getlist 应用场景:用户的爱好 多选框 # get只会获取到value列表的最后一个元素 # 获取get请求数据的方式跟post请求完全一样 print(request.GET) # <QueryDict: {'username': ['jason'], 'password': ['123']}> request.GET.get('user') # <QueryDict: {'username': ['jason','egon'], 'password': ['123']}> request.GET.getlist('username')
四、Django必备三件套
from django.shortcuts import render,HttpResponse,redirect ①HttpResponse 返回字符串 HttpResponse('hello world') ②render 返回一个html页面 render(request, 'reg.html') 两种给前端页面传值的方式 方式一:def reg(request): user_dict = {'name':'jason','password':'123'} return render(request,'reg.html',{'user_dict':user_dict}) 方式二:def reg(request): user_dict = {'name':'jason','password':'123'} return render(request,'reg.html',locals()) ③redirect 重定向 redirect('http://www.xiaohuar.com') django识别到你的代码变化之后会自动刷新,但是有时候反应速度比较慢, 你可以手动重启,也可以多刷新几次浏览器
def login(request): error_msg = "" if request.method == "POST": # 这里必须是大写的 # 如果你是POST请求,我就取出提交的数据,做登录判断 print(request.POST["email"]) email = request.POST.get("email", None) pwd = request.POST.get("pwd", None) print(email, pwd) # 做是否登陆成功的判断 if email == "alex@oldboyedu.com" and pwd == "alexdsb": # 登录成功 # 回复一个特殊的响应,这个响应会让用户的浏览器请求指定的URL return redirect("http://www.luffycity.com") else: # 登录失败 error_msg = "邮箱或密码错误" # 不是POST请求就走下面这一句 return render(request, "login.html", {"error": error_msg})
五、django连接数据库
1.需要修改settings配置文件 DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME': 'day54', 'HOST':'127.0.0.1', 'PORT':3306, 'USER':'root', 'PASSWORD':'3822515' } } ps:键必须都是大写 2.告诉django用pymysql替换它默认mysqldb模块连接数据库 方式1:在你的项目文件夹下面的__init__.py 默认在此init里写 方式2:也可以在你的应用文件夹下面的__init__.py # 固定写法 import pymysql pymysql.install_as_MySQLdb() # 告诉django用pymysql代替mysqldb连接数据库
六、数据库迁移命令
1、方式一:pycharm命令行
python3 manage.py makemigrations # 将你的数据库变动记录到一个小本本上(并不会帮你创建表) python3 manage.py migrate # 将你的数据库变动正在同步到数据库中
2、方式二:快捷键Tools
Tools --->>> Run manage.py Task makemigrations migrate
七、ORM
什么是ORM: 对象关系映射 类 >>> 表 对象 >>> 表记录 对象的属性 >>> 一条记录某个字段对应的值 django的ORM不能够自动帮你创建库,但是可以自动帮你创建表,所以需要自己手动创建库 提示:一个django项目就使用一个库,不要多个django项目使用一个库
优点:
1. 简单,不用自己写SQL语句
2. 开发效率高
缺点:
1. 记忆你这个特殊的语法
2. 相对于大神些的SQL语句,肯定执行效率有差距
ORM能做的事儿:
1. 操作数据表 --> 创建表/删除表/修改表
操作models.py里面的类
2. 操作数据行 --> 数据的增删改查
1. 自己动手创建数据库 create database 数据库名; 2. 在Django项目中设置连接数据库的相关配置(告诉Django连接哪一个数据库) # 数据库相关的配置 DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', # 连接的数据库类型 'HOST': '127.0.0.1', # 连接数据库的地址 'PORT': 3306, # 端口 'NAME': "day61", # 数据库名称 'USER': 'root', # 用户 'PASSWORD': '123456' # 密码 } } 3. 告诉Django用pymysql代替默认的MySQLDB 连接MySQL数据库 在项目/__init__.py文件中,写下面两句: import pymysql # 告诉Django用pymysql来代替默认的MySQLdb pymysql.install_as_MySQLdb() 4. 在app下面的models.py文件中定义一个类,这个类必须继承models.Model class 类名(models.Model): ... 5. 执行两个命令 1. python3 manage.py makemigrations 2. python3 manage.py migrate
八、ORM操作数据库
1、新增数据
# 方式1: user_obj = models.User.objects.create(name=username,password=password) # 方式2: user_obj = models.User(name=username,password=password) user_obj.save() # 对象调用save方法保存到数据库
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>添加用户</title> <meta name="viewport" content="width=device-width, initial-scale=1"> </head> <body> <form action="/add_user/" method="post"> <p>用户名: <input type="text" name="username"> </p> <p> <input type="submit" value="提交"> </p> </form> </body> </html>
#添加用户的函数 def add_user(request): if request.method == "POST": #用户填写了新的用户名,并发送了POST请求过来 new_name = request.POST.get("username",None) #去数据库中新创建一条记录 models.UserInfo.objects.create(name=new_name) #添加成功后直接跳转到用户列表页 return redirect("/user_list/") #第一次请求页面的时候,就返回一个页面,页面上有两个框让用户填写 return render(request,"add_user.html")
2、查询数据
user_list = models.User.objects.all() # 获取user表所有的数据 # 只要是QuerySet就可以点query查看获取到当前QuerySet对象的内部sql语句 print(user_list.query)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>用户列表页</title> </head> <body> <a href="/add_user/">添加用户</a> <table border="1"> <thead> <tr> <th>id值</th> <th>用户名</th> </tr> </thead> <tbody> {% for user in user_list %} <tr> <td>{{ user.id }}</td> <td>{{ user.name }}</td> </tr> {% endfor %} </tbody> </table> </body> </html>
#展示所有的用户的函数 def user_list(request): #去用户库中查询所有的用户 #利用ORM这个工具去查询数据库,不用自己去查询 ret=models.UserInfo.objects.all() #[UserInfo Object,UserInfo Object] print(ret[0].id,ret[0].name) #打开user_list.html文件 return render(request,"user_list.html",{"user_list":ret})
3、删除数据
models.User.objects.filter(id=1).delete() # 会将queryset所有的数据对象全部删除
def delete_user(request): # 从get请求携带的参数中获取用户想要删除的数据id delete_id = request.GET.get('delete_id') # print(delete_id) models.User.objects.filter(id=delete_id).delete() # print(res) # <QuerySet [<User: tank>]> # print(type(res)) # <class 'django.db.models.query.QuerySet'> return redirect('/userlist/')
4、编辑数据
编辑对象的id的获取方式 方式1:利用input隐藏一个标签 <input type="hidden" name="edit_id" value="{{ user_obj.pk }}"> 方式2: <form action="/edit/?edit_id={{ user_obj.pk }}" method="post"> 注意:queryset对象点修改 删除 会作用于对象内部所有的数据对象 类似于批量操作 方式1: models.User.objects.filter(id=edit_id).update(name=username,password=password) 方式2:获取到当前数据对象 user_obj = models.User.objects.filter(id=edit_id).first() user_obj.name = username user_obj.save()
def edit(request): if request.method == 'POST': username = request.POST.get('username') password = request.POST.get('password') # 获取编辑对象id的方式 edit_id = request.POST.get('edit_id') # 更新数据库 models.User.objects.filter(id=edit_id).update(name=username, password=password) return redirect('/userlist/') # 获取用户想要修改的数据的id edit_id = request.GET.get('edit_id') # 将该数据查询出来渲染到一个编辑页面 # 查询方式一 user_obj = models.User.objects.filter(id=edit_id).first() # 查询方式二 # user_obj = models.User.objects.get(id=edit_id) # 将当前数据渲染到一个编辑页面上 return render(request, 'edit.html', locals())
<!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="" method="post"> <input type="hidden" name="edit_id" value="{{ user_obj.pk }}"> <p>username:<input type="text" name="username" class="form-control" value="{{ user_obj.name }}"></p> <p>password:<input type="text" name="password" class="form-control" value="{{ user_obj.password }}"></p> <input type="submit" class="btn btn-warning"> </form> </div> </div> </div> </body> </html> edit.html