django系列10 --- 表单


前言

如果我们搭建的网站只发布内容且不接受客户的输入,那么就不需要表单。相反,如果你需要客户输入内容来做交互,那么就要使用表单来实现。
表单:django提供了一系列的工具和库帮助我们构建表单,目的是为了:接收、处理、响应客户在界面的输入。


一、html 表单

html代码中,<form>...</form>括起来的内容就是表单,它允许我们输入文本、选择选项、操作对象,然后将这些内容发送给服务端,也就是我们写的django代码中进行进一步处理表单需要制定2点:数据的URL地址、数据请求使用的http方法

1.1 get 和 post 方法

处理表单时,只会用到get和post方法,任何一个更改数据库的请求都应该使用post,get只用于不会影响系统状态(不更改数据库数据)的请求 。

  • django的登陆表单使用post方法传输数据,浏览器会封装表单数据,编码后传输给服务端。
  • get方法提交数据时,会将数据捆绑到一个字符串中,类似URl:https://docs.djangoproject.com/search/?q=forms&release=1

二、django在表单中的角色

处理表单是一个很复杂的业务流程,正常流程是:准备好多种不同类型的大量数据以在表单中显示、呈现为 HTML、使用方便的界面进行编辑、返回到服务器、验证和清理,然后保存或传递 用于进一步处理。使用django的表单可以简化以上内容,提高开发效率:

  1. 准备并重组数据,以便下一步的渲染
  2. 为数据创建 HTML 表单
  3. 接收并处理客户端提交的表单及数据

三、django中的表单

django 表单的核心类是 Form 类,与 model 大致相同,描述了对象的逻辑结果、行为、在网页上呈现给我们的方式。Form 类描述了一张表单并决定了它如何运行和呈现在网页上,在浏览器中,表单字段以 HTML控件 的形式展现给我们,Form 类的每个字段类型都有与之匹配的控件类,

四、构建一张表单

4.1 form类

根目录下生成 forms.py 文件,django中表单内容:

from django import forms

class NameForm(forms.Form):
    your_name = forms.CharField(label='Your name', max_length=100)

每个form实例都有 is_valid() 方法,如果用户输入了内容,则返回True且将表单数据存储在属性cleaned_data中,

4.2 视图

django网站的表单数据会交给后台的视图(views.py)来处理,为了处理表单数据,我们需要将它实例化到我们希望的URL中

# views.py
from django.http import HttpResponseRedirect
from django.shortcuts import render

from .forms import NameForm

def get_name(request):
    if request.method == 'POST':
        # 如果这个表单是post请求,我们需要处理数据
        form = NameForm(request.POST)
        if form.is_valid():  # 检查界面是否传入表单数据
            # 表单数据被存储在 form.cleaned_data 中
            return HttpResponseRedirect('/thanks/')  # 返回一个界面,输入该界面的URL
    else:
        # 如果是一个get请求,将创建一个空表单
        form = NameForm()
    return render(request, 'name.html', {'form': form})

4.3 模板

其中 {{ form }} 中的form是get_name()里的变量 form = NameForm(),把我们自定义的这个表单类传入到界面

<form action="/your-name/" method="post">
    {% csrf_token %}
    {{ form }}
    <input type="submit" value="Submit">
</form>

表单API,参考:https://docs.djangoproject.com/zh-hans/4.0/ref/forms/api/#django.forms.Form

五、详解 django 表单的类

5.1 表单实例

表单分为2类,绑定和未绑定

  • 未绑定数据的表单,当渲染给用户时,它是空或者包含默认值
  • 绑定的表单拥有已提交的数据,因此可以用来判断数据是否合法,表单的is_bound属性用来判断是否具有绑定的数据

5.2 字段详解

from django import forms

class ContactForm(forms.Form):
    subject = forms.CharField(max_length=100)
    message = forms.CharField(widget=forms.Textarea)
    sender = forms.EmailField()
    cc_myself = forms.BooleanField(required=False)

如上表单,拥有的字段分别是: CharField 、 EmailField 和 BooleanField
(1)控件
每个表单字段都有一个控件类,控件类对应html表单控件,例如:<input type="text">每个表单字段都有一个默认控件,比如charfield默认控件是 TextInput,如果要指定控件如下:

from django import forms
class RunApiForm(forms.Form):
    query_params = forms.CharField(label='查询参数', required=False, widget=forms.Textarea(attrs={'rows': 6,'cols': 80,}))

(2)字段数据
表单数据通过调用 is_valid() 验证成功,已验证的表单数据会被放到form.cleaned_data 字典中,数据已经被转换成 python 类型,但我们依然可以从 request.POST 中访问未验证的数据。最好还是使用校验后的数据,视图中处理表单数据:

# views.py
from django.core.mail import send_mail
from django import forms
from .forms import NameForm
from django.http import HttpResponseRedirect
from django.shortcuts import render

def get_name(request):
    if request.method == 'POST':
        form = NameForm(request.POST)
        if form.is_valid():
            subject = form.cleaned_data['subject']
            message = form.cleaned_data['message']
            sender = form.cleaned_data['sender']
            cc_myself = form.cleaned_data['cc_myself']
        
            recipients = ['info@example.com']
            if cc_myself:
                recipients.append(sender)
        
            send_mail(subject, message, sender, recipients)
            return HttpResponseRedirect('/thanks/')
    else:
        # 如果是一个get请求,将创建一个空表单
        form = NameForm()
    return render(request, 'name.html', {'form': form})

完成字段参考:https://docs.djangoproject.com/zh-hans/4.0/ref/forms/fields/

六、使用 django 表单模板

只需要将表单实例放到表单模板中即可,例如上面的 NameForm() 实例 form,传入表单模板 name.html 中,

    else:
            # 如果是一个get请求,将创建一个空表单
            form = NameForm()
        return render(request, 'name.html', {'form': form})

6.1 表单渲染选项

表单在界面是以什么形式展现,分为三种 表格、段落、列表呈现

  • {{ form.as_table }} 将它们呈现为包含在标签中的表格单元格
  • {{ form.as_p }}将它们包裹在<p>标签中
  • {{ form.as_ul }}将它们包裹在<li>标签中
<form action="/your-name/" method="post">
    {% csrf_token %}
    {{ form }}
    <input type="submit" value="Submit">
</form>

<form action="/your-name/" method="post">
    {% csrf_token %}
    {{ form.as_table }}
    <input type="submit" value="Submit">
</form>

<form action="/your-name/" method="post">
    {% csrf_token %}
    {{ form.as_p }}
    <input type="submit" value="Submit">
</form>

<form action="/your-name/" method="post">
    {% csrf_token %}
    {{ form.as_table }}
    <input type="submit" value="Submit">
</form>

6.2 手动渲染字段(ing)

(1)每个字段都可以用作为表单的一个属性,并被响应的渲染到django模板中,显示例如:

{{ form.non_field_errors }}
<div class="fieldWrapper">
    {{ form.subject.errors }}
    <label for="{{ form.subject.id_for_label }}">Email subject:</label>
    {{ form.subject }}
</div>
<div class="fieldWrapper">
    {{ form.message.errors }}
    <label for="{{ form.message.id_for_label }}">Your message:</label>
    {{ form.message }}
</div>
<div class="fieldWrapper">
    {{ form.sender.errors }}
    <label for="{{ form.sender.id_for_label }}">Your email address:</label>
    {{ form.sender }}
</div>
<div class="fieldWrapper">
    {{ form.cc_myself.errors }}
    <label for="{{ form.cc_myself.id_for_label }}">CC yourself?</label>
    {{ form.cc_myself }}
</div>

(2)渲染表单的错误信息(ing)

6.3 遍历表单字段

(1)如果要给每个字段使用相同的html控件,则使用 {% for %} 依次循环处理:

{% for field in form %}
    <div class="fieldWrapper">
        {{ field.errors }}
        {{ field.label_tag }} {{ field }}
        {% if field.help_text %}
        <p class="help">{{ field.help_text|safe }}</p>
        {% endif %}
    </div>
{% endfor %}

(2)遍历隐藏字段和可见字段(ing)

6.4 可复用的表单模板

你可以通过将表单的循环保存在一个独立的模板中,并覆盖表单的 template_name 属性来使用自定义模板渲染表单,从而减少重复。

# In your template:
{{ form }}

# In form_snippet.html:
{% for field in form %}
    <div class="fieldWrapper">
        {{ field.errors }}
        {{ field.label_tag }} {{ field }}
    </div>
{% endfor %}
  • 2
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

阿_焦

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值