Django——视图
Django项目中的视图相当于Python的函数或者类;Django接收到浏览器发送的请求,视图就会接收这个请求并且对其作出响应。
视图中第一个参数必须是 HttpRequest 的对象 (一般情况下,我们默认写为 request)
视图中必须返回一个 HttpResponse 对象或者其子类对象作为响应。
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就会将这个对象作为第一个参数传入到视图中。
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
登录视图
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('登录失败')
<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中
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 处理响应内容
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 类实现的。
class MyView(View): # 按照需要的请求方式定义不同的请求方法 # 请求方法的方法名就是请求方式名 def get(self , request): # get 请求触发的方法 return HttpResponse('get 请求') def post(self , request): # post 请求触发 return HttpResponse('post请求')
路由配置
# 类视图的 url 映射 # as_view() 对类视图进行调用 path('my/' , views.MyView.as_view())
as_view 源码
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源码
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)
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、上传文件
path('file/' , views.GetFileView.as_view()),
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('文件上传成功')
<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>