Django------视图
Django项目中的视图相当于Python的函数或者类;Django接收到浏览器发送的请求,视图就会接收这个请求并且对其作出响应。
视图中第一个参数必须是 HttpRequest 的对象 (一般情况下,我们默认写为 request)
视图中必须返回一个 HttpResponse 对象或者其子类对象作为响应。
python
def index(request):
response = HttpResponse('index')
return response
def get_html(request):
# 模板化:将 html 文件转换为带有前端 标签的字符串
# 在 render 方法内部 , 将转换好的字符串使用 HttpResponse 对象进行返回作为响应
return render(request , 'index.html')
def coll(request):
# redirect url 重定向
# redirect 方法内部返回的是 HttpResponse 的子类 : HttpResponseRedirect 对象
# 状态码是: 302
return redirect(index)
1、请求:HttpRequest
HttpRequest 是 Django 在视图中处理 HTTP 请求操作。
当浏览器发送请求到项目中 , Django接收到请求并且匹配到对应的url和视图的映射关系之后,创建 HttpRequest 对象。这个对象中封装了请求的所有数据。当触发视图的时候, Django就会将这个对象作为第一个参数传入到视图中。
python
def index(request):
# 获取请求方法 # GET
print(request.method)
# 获取到请求中的参数:GET
# 正常情况下 , GET和 POST请求的参数会以字典的方式被封装到request中
# http://127.0.0.1:8000/index/?name=ac&age=27
name = request.GET.get('name')
age = request.GET.get('age')
print(name , age)
# 获取 url 中的请求路径
# /index/ , 只获取请求的 url , 不携带参数
url_path = request.path
# /index/?name=ac&age=27 ,获取请求中的 url , 携带参数
get_full_path = request.get_full_path()
print(url_path)
print('*'*20)
print(get_full_path)
response = HttpResponse('index')
return response
登录视图
python
def login_view(request):
# 判断 请求方式:GET 响应 html 页面 ; POST 对用户提交的数据进行判断验证
if request.method == "GET":
return render(request , 'login.html')
# 请求为 POST
# 获取用户提交过来的数据 , 数据名就是表单中的 name 属性值
name = request.POST.get('username')
password = request.POST.get('password')
# 判断数据
if name == 'ac' and password == '123':
return HttpResponse('登录成功')
else:
return HttpResponse('登录失败')
html
<body>
<form method="post">
{% csrf_token %}
<input type="text" name="username" placeholder="用户名">
<input type="password" name="password" placeholder="密码">
<input type="submit" value="登录">
</form>
</body>
2、响应:HttpResponse
Django 提供了 HttpResponse 子类的作为响应状态 , 这些子类封装在 django.http中
python
from django.http import HttpResponseRedirect , HttpResponseForbidden
def status_302(request):
# HttpResponseRedirect 等同于 redirect
return HttpResponseRedirect('/login/')
def status_403(request):
return HttpResponseForbidden('请求被拒绝')
def status_404(request):
# 直接指定 HttpResponse 对象的响应状态
return HttpResponse('你好',status=404)
HttpResponse 处理响应内容
python
def response_view(request):
# content_type 设置响应文本格式 ,字符编码
# text/plain 表示内存为存文本格式
# text/html 表示内容以 html 文本格式
response_data = HttpResponse('<h1>各位靓仔 , 靓女晚上好</h1>' ,content_type="text/plain;charset=utf-8")
return response_data
3、类视图
类视图,是把函数视图中封装的请求方式进行拆分,将请求中的不同种请求方式封装为一个独立的方法中。
django 中的类视图是基于 django.views.View 类实现的。
python
class MyView(View):
# 按照需要的请求方式定义不同的请求方法
# 请求方法的方法名就是请求方式名
def get(self , request):
# get 请求触发的方法
return HttpResponse('get 请求')
def post(self , request):
# post 请求触发
return HttpResponse('post请求')
路由配置
python
# 类视图的 url 映射
# as_view() 对类视图进行调用
path('my/' , views.MyView.as_view())
as_view 源码
python
def as_view(cls, **initkwargs):
def view(request, *args, **kwargs):
# cls as_view用来调用当前的类
# 调用之后生成的对象 ------ self
self = cls(**initkwargs)
self.setup(request, *args, **kwargs)
# hasattr 判断对象的属性与方法是否存在
# 判断 HttpRequest 的对象是否存在
if not hasattr(self, 'request'):
raise AttributeError(
"%s instance has no 'request' attribute. Did you override "
"setup() and forget to call super()?" % cls.__name__
)
return self.dispatch(request, *args, **kwargs)
return view
dispatch源码
python
def dispatch(self, request, *args, **kwargs):
# 请求方式列表
# http_method_names = ['get', 'post', 'put', 'patch', 'delete', 'head', 'options', 'trace']
# 判断当前的请求是否在请求方式列表中
if request.method.lower() in self.http_method_names:
# getattr 调用类中的属性或者方法
# 在映射的对应类视图中 , 调用 request.method.lower() 与之同名的方法
# 当类视图中没有定义对应的请求 ,则返回http_method_not_allowed ,触发 405 状态响应 , 请求方式不存在
handler = getattr(self, request.method.lower(), self.http_method_not_allowed)
else:
# 触发 405 状态响应 , 请求方式不存在
handler = self.http_method_not_allowed
return handler(request, *args, **kwargs)
python
class MyView(View):
# 按照需要的请求方式定义不同的请求方法
# 请求方法的方法名就是请求方式名
def get(self , request):
# get 请求触发的方法
return render(request , 'login.html')
def post(self , request):
# post 请求触发
name = request.POST.get('username')
password = request.POST.get('password')
# 判断数据
if name == 'ac' and password == '123':
return HttpResponse('登录成功')
else:
return HttpResponse('登录失败')
4、上传文件
python
path('file/' , views.GetFileView.as_view()),
python
class GetFileView(View):
def get(self , request):
return render(request , 'get_file.html')
def post(self , request):
# 获取到file的文件对象
file = request.FILES.get('file')
# 获取文件名
file_name = file.name
# 拼接文件要保存的位置
# 获取到项目的根目录
from django_view.settings import BASE_DIR
import os
# 拼接路径
file_dir = os.path.join(BASE_DIR , 'File' , file_name)
# 将获取到的文件对象保存到这个路径中
# 把上传的文件重新写入到项目的指定位置
with open(file_dir , 'wb') as f:
# file 是文件对象
# 获取对象中的数据要用循环的方式
for i in file:
f.write(i)
return HttpResponse('文件上传成功')
html
<body>
<form method="post" enctype="multipart/form-data">
<!--
文件上传需要用二进制的方式上传
form表单提交的数据默认时键值对的方式读取:application/x-www-form-urlencoded
二进制读取方式:multipart/form-data
-->
{% csrf_token %}
文件:<input type="file" name="file"><br>
<input type="submit" value="上传">
</form>
</body>