[Python自学] day-19 (Django框架)

本章目录:

一、获取表单提交的数据

在 [Python自学] day-18 (2) (MTV架构、Django框架) 中,我们使用过以下方式来获取表单数据:

user = request.POST.get('username', None)

这种获取方式可以获取来自表单的单个数据,例如<input type='text'/>的数据。

除了以上这种最简单的数据获取方式,我们还需要获取例如<input type='checkbox' />、<input type='file' />、<select>等标签的数据:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>MyPage</title>
    <style>
        p{
            border: 1px solid #dddddd;
            display: inline-block;
        }
    </style>
</head>
<body>
    <form action="/mypage" method="post" enctype="multipart/form-data">
        <!-- radio单选 -->
        <p>性别:</p>
        <div>
            男:<input type="radio" name="gender" value="1"/>
            女:<input type="radio" name="gender" value="2"/>
        </div>
        <!-- checkbox多选 -->
        <p>喜好:</p>
        <div>
            足球:<input type="checkbox" name="favor" value="11"/>
            篮球:<input type="checkbox" name="favor" value="22"/>
            游泳:<input type="checkbox" name="favor" value="33"/>
        </div>
        <!-- 单选select -->
        <p>来自哪个城市:</p>
        <div>
            <select name="city">
                <option value="cd">成都</option>
                <option value="bj">北京</option>
                <option value="sh">上海</option>
            </select>
        </div>
        <!-- 多选select -->
        <p>喜欢哪些城市:</p>
        <div>
            <select name="favorcity" multiple>
                <option value="cd">成都</option>
                <option value="bj">北京</option>
                <option value="sh">上海</option>
            </select>
        </div>
        <!-- 上传文件 -->
        <div>
            <input type="file" name="filetrans"/>
        </div>
        <div style="height: 48px;line-height: 48px;">
            <input type="submit" value="提交"/>
        </div>
    </form>
</body>

在views.py中,我们可以通过以下方式来获取对应的数据:

def mypage(request):
    if request.method == 'POST':
        print(request.POST.get('gender', None))  # 获取radio单选数据,打印单个数据,例如'2'表示"女"
        print(request.POST.getlist('favor', None))  # 获取checkbox的多选数据,打印value组成的列表 ['11','22']
        print(request.POST.get('city', None))  # 获取select的单选数据,打印单个数据,例如'cd'表示"成都"
        print(request.POST.getlist('favorcity', None))  # 获取multiple select标签的多选数据,打印列表['cd','sh']

        # 获取文件对象
        recv_file = request.FILES.get('filetrans', None)
        print(recv_file.name)
        # 从obj.chunks()中循环获取文件的块,并写入同名文件
        with open(os.path.join('upload', recv_file.name), 'wb') as f:
            for i in recv_file.chunks():
                f.write(i)

    return render(request, 'mypage.html')

特别注意:在上传文件的时候,<form>表单必须要有 enctype="multipart/form-data" 属性,否则会将文件当做字符串提交(也就是说后台只能收到文件的名称)。

二、FBV和CBV

FBV:Function base view,基于函数的视图。

CBV:Class base view,基于类的视图。

1.FBV

在之前的章节中,我们在APP的views.py中写了很多请求处理函数(视图函数),使用函数来处理请求,就叫做FBV。

2.CBV

如果我们使用一个类来处理一个URL,则称为CBV,例如在APP的views.py中定义一个处理类:

from django.views import View


# 处理类必须继承自View类
class MyPage(View):
    # get方法专门处理GET请求
    def get(self, request):
        print(request.method)
        return render(request, 'mypage.html')

    # post方法专门处理POST请求
    def post(self, request):
        print(request.method)
        return render(request, 'mypage.html')

我们查看View类的源码,可以看到:

class View:
    """
    Intentionally simple parent class for all views. Only implements
    dispatch-by-method and simple sanity checking.
    """

    http_method_names = ['get', 'post', 'put', 'patch', 'delete', 'head', 'options', 'trace']

    ......
    ......

我们可以定义 http_method_names 列表中所列出的所有请求类型对应的方法。

3.CBV中的执行过程

 我们查看View父类的源码:

    def dispatch(self, request, *args, **kwargs):
        # Try to dispatch to the right method; if a method doesn't exist,
        # defer to the error handler. Also defer to the error handler if the
        # request method isn't on the approved list.
        if request.method.lower() in self.http_method_names:
            handler = getattr(self, request.method.lower(), self.http_method_not_allowed)
        else:
            handler = self.http_method_not_allowed
        return handler(request, *args, **kwargs)

我们可以看到使用反射的时候,参数中将请求方式转化为小写。所以,我们实现的方法名必须是小写的。例如get()、post()、put()。如果请求的方法不在允许的列表中,则返回405错误(参考源码中的 self.http_method_not_allowed方法)。

猜你喜欢

转载自www.cnblogs.com/leokale-zz/p/12054611.html
今日推荐