Django——视图

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>
相关推荐
苏三说技术12 小时前
Claude Code从失控到起飞,只用了这些技巧
后端
aqi0012 小时前
15天学会AI应用开发(七)有了大模型为什么还要引入RAG
人工智能·python·大模型·ai编程·ai应用
长栎13 小时前
写 for 循环写了十年,你却从没用过迭代器模式最狠的那一面
后端
LiaCode13 小时前
Redis 在生产项目的使用
前端·后端
用户5598224812213 小时前
Docker Compose Down 导致容器数据误删——ext4 日志恢复全记录
后端
LiaCode13 小时前
一天学完 redis 的爽翻版核心知识总结
前端·后端
大刚测试开发实战13 小时前
如何内网穿透访问本地私有化部署的TestHub
前端·后端·github
xiaodaoluanzha13 小时前
迄今為止,最簡單的編程語言 Nolang
前端·后端
Csvn13 小时前
Docker 容器管理入门 — 从镜像到容器编排
后端