信息发布→ 登录 注册 退出

Python Django框架中表单的用法详解

发布时间:2026-01-11

点击量:
目录
  • 文件上传
    • Form表单
    • 表单字段
    • 字段参数
    • widget参数
    • 表单的验证
  • 表单模型文件上传例子
    • 模型表单
      • AJAX

        Django保证表单的正确显示需要添加CSRF(防止网站跨站请求伪造而默认开启的一种保护方式),在<form></form>之间添加

        {% csrf_token %}

        在项目settings.py中 * ‘django.middleware.csrf.CsrfViewMiddleware’, * 引入,如果没有此中间件,手动添加。

        文件上传

        首次打开路径是GET请求,如果点击上传是POST请求,如果文件内容不为空,则上传文件,上传路径为主项目下的 media/uploads/,如果路径不存在则新建。open(os.path.join(path + myFile.name), ‘wb+’) 二进制读写打开对应文件,chunks()将文件分块读写。

        def upload_file(request):
            if request.method == "GET":
                return render(request, 'app1/upload.html')
            if request.method == "POST":
                myFile = request.FILES.get("myfile", None)
                if myFile:
                    path = 'media/uploads/'
                    if not os.path.exists(path):
                        os.makedirs(path)
                    dest = open(os.path.join(path + myFile.name), 'wb+')
                    for chunk in myFile.chunks():
                        dest.write(chunk)
                    dest.close()
                    return HttpResponse("上传完成")
                else:
                    return HttpResponse("没有上传文件")
        

        添加路由。

        文件已经上传成功。

        Form表单

        如下新建一个form.py写入如下代码

        from django import forms
        
        class UserInfoForm(forms.Form):
            '''用户状态'''
            STATUS = ((None, '请选择'), (0, '正常'), (1, '无效'),)
            username = forms.CharField(label="用户名称", min_length=6, widget=forms.widgets.TextInput(
                attrs={'class': 'form-control', 'placeholder': '请输入用户名称'}
            ))
            password = forms.CharField(label="密码", min_length=6, max_length=10, widget=forms.widgets.PasswordInput(
                attrs={'class': 'password'}, render_value=True
            ))
            age = forms.IntegerField(label="年龄", initial=1)
            mobile = forms.IntegerField(label="手机号码")
            status = forms.ChoiceField(label="用户状态", choices=STATUS)
            createdate = forms.DateTimeField(label="创建时间", required=False)
        

        表单字段

        表单字段说明
        CharField文本输入
        InterField/FloatField/DecimalField数值输入
        ChoiceField选择输入框 choices指定下拉列表
        FileField文件
        BooleanField复选框
        DateField/DateTimeField/TimeField时间输入框,可以设置输入格式 input_format=[“%Y-%m-%d %H:%M”]
        EmailField邮件输入框
        URLField路劲输入框
        ModelChoiceField从数据库获取下拉列表

        字段参数

        字段说明
        labellabel标签
        label_suffixLabel标签统一后缀信息
        initial初始值
        help_text字段描述信息
        error_messages字段描述信息
        validators验证规则
        required是否必须
        disabled字段是否可编辑
        widget指定HTML样式

        widget参数

        参数说明
        PasswordInput密码输入框
        HiddenInput隐藏元素
        Textarea文本域
        CheckboxInput复选框
        FileInput文件输入框
        RadioSelect单选按钮
        DateTimeInput时间输入框
        Select下拉列表
        SelectMuitiple多选框

        配置视图和路径显示对应表单

        app1下的views.py

        def userinfo_form(request):
            if request.method == "GET":
                myForm = UserInfoForm()
        
                return render(request, 'app1/userinfo.html', {'form_obj': myForm})
        

        userinfo.html

        <html>
          <head></head>
          <body>
            <form action="" method="POST">
              {% csrf_token %} {{ form_obj.as_p }}
              <input type="submit" value="提交" />
            </form>
          </body>
        </html>

        • as_p 为表单提供<p>标签
        • as_table 为表单提供<table>标签
        • as_ui 为表单提供<ui>标签

        以上用了as_p,故源代码显示p标签。

        表单的验证

        • is_valid() 验证表单数据是否合法
        • cleaned_data 获取表单通过验证的数据
        • errors 表单验证的错误信息

        在form中添加如下代码

        class UserInfoForm__Msg(forms.Form):
            '''用户状态'''
            STATUS = ((None, '请选择'), (0, '正常'), (1, '无效'),)
            username = forms.CharField(label="用户名称", min_length=6, widget=forms.widgets.TextInput(
                attrs={'class': 'form-control', 'placeholder': '请输入用户名称'}
            ), error_messages={
                'required': '用户姓名不能为空', 'min_length': '长度不能少于6位', 'invalid': '不能含有特殊字符'
            })
            password = forms.CharField(label="密码", min_length=6, max_length=10, widget=forms.widgets.PasswordInput(
                attrs={'class': 'password'}, render_value=True
            ), error_messages={
                'required': '密码不能为空', 'min_length': '密码不能少于6位', 'max_length': '密码不能多余10位',
            })
            age = forms.IntegerField(label="年龄", initial=1, validators=[age_validate], error_messages={
                'required': '年龄不能为空',
            })
            mobile = forms.IntegerField(label="手机号码", validators=[mobile_validate], error_messages={
                'required': '手机号码不能为空',
            })
            status = forms.ChoiceField(label="用户状态", choices=STATUS, error_messages={
                'required': '用户状态不能为空',
            })
            createdate = forms.DateTimeField(label="创建时间", required=False)
        
        • required 为空的时候的错误信息
        • invalid 格式验证错误的信息
        • min_length和max_length 长度不在设定的范围的错误信息

        添加视图

        def userinfo_form_msg(request):
            if request.method == "GET":
                myForm = UserInfoForm__Msg()
                return render(request, 'app1/userinfoform.html', {'form_obj': myForm})
            else:
                f = UserInfoForm__Msg(request.POST)
                if f.is_valid():
                    print(f.cleaned_data['username'])
                else:
                    errors = f.errors
                    print(errors)
                    return render(request, 'app1/userinfoform.html', {'form_obj': f, 'errors': errors})
                return render(request, 'app1/userinfoform.html', {'form_obj': f})
        

        模板文件

        <form action="" method="POST" novalidate>
          {% csrf_token %}
          <p>
            {{ form_obj.username.label }}:{{ form_obj.username }} {{ errors.username.0 }}
          </p>
          <p>{{ form_obj.password}}{{ errors.password.0 }}</p>
          <p>{{ form_obj.status.label }}:{{ form_obj.status }} {{ errors.status.0 }}</p>
          <p>{{ form_obj.age.label }}:{{ form_obj.age }} {{ errors.age.0 }}</p>
          <p>{{ form_obj.mobile.label }}:{{ form_obj.mobile }} {{ errors.mobile.0 }}</p>
          错误信息汇总: {{ errors }}
          <input type="submit" value="提交" />
        </form>
        

        这里还添加了表单的自我格式验证,获取表单的数据

        • f.clean() 获取全部数据
        • f.clean_date[] 获取对应值的数据
        • f.data 获取全部数据

        表单模型文件上传例子

        模板文件:upload_form.html

        <form enctype="multipart/form-data" action="" method="post">
          {% csrf_token %} {{ form_obj.as_p }}
          <br />
          <input type="submit" value="文件上传" />
          <img src="media/uploads/{{ user.heading }}"
        </form>

        模型文件

        在models.py中添加模型,这里没有主键默认会生成id的主键

        class ImgFile(models.Model):
            name = models.CharField(verbose_name='用户名称', max_length=300, default="")
            heading = models.FileField(verbose_name='文件名', upload_to='media/uploads/')
        
            def __str__(self):
                return self.name
        
            class Meta:
                verbose_name = ' 用户头像信息'
                db_table = 'user_img'
        

        表单模型 form.py

        class ImgFileForm(forms.Form):
            name = forms.CharField()
            heading = forms.FileField()
        

        视图模型

        如果上传了文件,将文件保存在对应的目录下,并返回文件的信息。

        def ingfileform(request):
            if request.method == "GET":
                f = ImgFileForm()
                return render(request, 'app1/upload_form.html', {'form_obj': f})
            else:
                f = ImgFileForm(request.POST, request.FILES)
                if f.is_valid():
                    name = f.cleaned_data['name']
                    heading = f.cleaned_data['heading']
                    path = 'media/uploads/'
                    if not os.path.exists(path):
                        os.makedirs(path)
                    dest = open(os.path.join(path + heading.name), 'wb+')
                    for chunk in heading.chunks():
                        dest.write(chunk)
                    dest.close()
        
                    userimg = ImgFile()
                    userimg.name = name
                    userimg.heading = heading
                    userimg.save()
                    print('上传成功')
                    return render(request, 'app1/upload_form.html', {'form_obj': f, 'user': userimg})
                else:
                    print(f.errors)
        

        路由

        re_path 配置了可以直接在浏览器访问对应的文件,

        from django.urls import path, include, re_path
        from django.views.static import serve
        from mywed import settings
            path('app1/userimg/', views.ingfileform),
            re_path('media/uploads/(?P<path>.*)', serve,
                    {"document_root": settings.MEDIA_ROOT}),
        

        settings.py

        这里路径在项目文件中设置便于统一,在实际的应用中也应该多在公共文件中设置

        MEDIA_URL = "media/uploads/"
        MEDIA_ROOT = os.path.join(MEDIA_URL, "")

        db中也登陆了对应的信息

        模型表单

        Django提供了ModelForm可以直接和模型关联,省略了Form表单中定义的操作。

        AJAX

        模板文件,为了能够正常的访问,必须添加csrfmiddlewaretoken或者在视图函数中注释@csrf_exempt,建议使用第一种方式

        用户名:<input type="text" id="username"></input>
        密码:<input type="password" id="password"></input>
        {% csrf_token %}
        <button id="submit">提交</button>
        <script src="https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js"></script>
        <script>
        
        $("#submit").click(function(){
            var csrf = $('input[name="csrfmiddlewaretoken"]').val();
            $.ajax({
              url: '/app1/ajax_login_data',
              type: "post",
              data: {
                'username': $("#username").val(),
                'password': $("#password").val(),
                'csrfmiddlewaretoken': csrf
              },
              success: function(data){
                console.log(data)
              },
              error: function(jqXHR, textStatus, err){
                console.log(arguments);
              }
            });
          }); 
        </script>
        

        视图文件

        from django.views.decorators.csrf import csrf_exempt
        def ajax_login(request):
            return render(request, 'app1/ajax.html')
        
        
        # @csrf_exempt
        def ajax_login_data(request):
        
            if request.method == "GET":
                HttpResponse("内部自己的url")
            username = request.POST.get('username')
            password = request.POST.get('password')
            print(username)
            if username == 'admin' and password == '123456':
                return JsonResponse({
                    'code': 1,
                    'msg': "登陆成功"
                })
            else:
                print("222")
                return JsonResponse({
                    'code': 0,
                    'msg': "登陆失败"
        

        这里使用的是网上的jquery地址,也可在settings.py匹配如下,在网站根目录中创建static目录,放入jquery文件。

        <script src=“/statics/jquery.min.js”></script>

        STATIC_URL = '/statics/'
        
        ​​​​​​​STATICFILES_DIRS = [
            os.path.join(BASE_DIR, "statics"),
        ]
        

        以上就是Python Django框架中表单的用法详解的详细内容,更多关于Python Django表单的资料请关注其它相关文章!

        在线客服
        服务热线

        服务热线

        4008888355

        微信咨询
        二维码
        返回顶部
        ×二维码

        截屏,微信识别二维码

        打开微信

        微信号已复制,请打开微信添加咨询详情!