目录

  1. 什么是 Django 表单?
  2. 创建 Django 表单
  3. Django 表单字段
  4. 验证表单数据
  5. 处理表单数据
  6. 表单类与视图集成
  7. 常见问题与解决方案
  8. 参考资料

1. 什么是 Django 表单?

Django 表单系统使得用户能够通过网页与后台服务器进行交互,提交数据并进行验证。Django 提供了强大的表单类,能够简化用户输入数据的处理,支持字段验证、错误提示以及表单渲染等功能。

表单的作用

  • 用户输入:表单用于收集用户的数据,如注册、登录、评论等。
  • 数据验证:表单会自动执行字段级别的验证,确保用户输入的数据符合要求。
  • 安全性:Django 表单包括防止 CSRF 攻击的机制,增强应用的安全性。

2. 创建 Django 表单

2.1 创建表单类

在 Django 中,可以通过继承 django.forms.Form 类来创建表单。每个表单字段都应该是表单类中的一个属性。

例如,创建一个简单的联系表单:

# myapp/forms.py

from django import forms

class ContactForm(forms.Form):
    name = forms.CharField(max_length=100, required=True, label='姓名')
    email = forms.EmailField(required=True, label='邮箱')
    message = forms.CharField(widget=forms.Textarea, required=True, label='留言')

在上述表单中,我们定义了三个字段:

  • name: 用户姓名,最大长度 100 字符。
  • email: 用户邮箱,必须是有效的电子邮件格式。
  • message: 用户留言,使用 Textarea 小部件来呈现一个多行文本框。

3. Django 表单字段

Django 提供了多种字段类型,常见的包括:

  • CharField:用于处理字符串字段。
  • EmailField:用于处理电子邮件字段。
  • IntegerField:用于处理整数字段。
  • FloatField:用于处理浮动数值字段。
  • BooleanField:用于处理布尔字段(True/False)。
  • ChoiceField:用于处理选择列表。
  • DateFieldDateTimeField:用于处理日期或时间字段。
  • FileField:用于处理文件上传。

例如,创建一个带有选择字段的表单:

class SurveyForm(forms.Form):
    name = forms.CharField(max_length=100)
    feedback = forms.ChoiceField(choices=[('good', '很好'), ('bad', '不好')])


4. 验证表单数据

Django 表单会自动进行数据验证,确保数据符合预期。如果用户输入的数据无效,Django 会为每个字段生成错误消息。

4.1 字段级验证

你可以为每个字段定义额外的验证逻辑。例如,验证邮箱格式:

class ContactForm(forms.Form):
    email = forms.EmailField()

    def clean_email(self):
        email = self.cleaned_data.get('email')
        if "example.com" in email:
            raise forms.ValidationError("禁止使用 example.com 邮箱")
        return email

4.2 表单级验证

如果需要在多个字段之间进行验证,可以定义表单级别的 clean 方法:

class ContactForm(forms.Form):
    start_date = forms.DateField()
    end_date = forms.DateField()

    def clean(self):
        cleaned_data = super().clean()
        start_date = cleaned_data.get("start_date")
        end_date = cleaned_data.get("end_date")

        if end_date < start_date:
            raise forms.ValidationError("结束日期不能早于开始日期")
        return cleaned_data


5. 处理表单数据

在视图中,我们可以接收表单提交的数据并进行处理。Django 会在请求中包含表单数据,通常是通过 POST 方法提交的。

5.1 视图中的表单处理

创建视图来显示和处理表单:

# myapp/views.py

from django.shortcuts import render
from .forms import ContactForm

def contact_view(request):
    if request.method == 'POST':
        form = ContactForm(request.POST)
        if form.is_valid():
            # 表单数据验证通过
            name = form.cleaned_data['name']
            email = form.cleaned_data['email']
            message = form.cleaned_data['message']
            # 处理表单数据(如发送电子邮件、保存数据库等)
            return render(request, 'thank_you.html', {'name': name})
    else:
        form = ContactForm()

    return render(request, 'contact.html', {'form': form})

在这个视图中,我们:

  • 如果请求是 POST 方法,表示表单被提交,我们使用 ContactForm(request.POST) 获取表单数据。
  • 使用 form.is_valid() 方法检查表单数据是否有效。
  • 如果有效,我们获取清理过的数据(form.cleaned_data),然后进行进一步处理。

5.2 渲染表单

在模板中渲染表单:

<!-- contact.html -->
<form method="post">
    {% csrf_token %}
    {{ form.as_p }}  <!-- 渲染表单字段 -->
    <button type="submit">提交</button>
</form>

form.as_p 会将表单字段渲染为 <p> 标签中的内容,你也可以使用 form.as_table 或自定义 HTML 来渲染表单。


6. 表单类与视图集成

Django 还支持基于类的视图(CBV)来处理表单,使用 FormView 类可以简化表单的展示与处理。

6.1 使用 FormView

# myapp/views.py

from django.views.generic.edit import FormView
from .forms import ContactForm

class ContactFormView(FormView):
    template_name = 'contact.html'
    form_class = ContactForm
    success_url = '/thank-you/'

    def form_valid(self, form):
        # 在表单验证通过时,处理表单数据
        name = form.cleaned_data['name']
        email = form.cleaned_data['email']
        message = form.cleaned_data['message']
        # 处理数据(如发送电子邮件等)
        return super().form_valid(form)

urls.py 中配置路由:

from django.urls import path
from .views import ContactFormView

urlpatterns = [
    path('contact/', ContactFormView.as_view(), name='contact'),
]

使用 FormView 后,Django 会自动处理表单的显示、验证和数据保存等操作。


7. 常见问题与解决方案

1. 表单不显示错误消息

  • 确保模板中渲染了错误消息。可以使用 {{ form.errors }} 来显示所有字段的错误。
{% for field in form %}
    <div class="form-group">
        <label for="{{ field.id_for_label }}">{{ field.label }}</label>
        {{ field }}
        {% for error in field.errors %}
            <div class="error">{{ error }}</div>
        {% endfor %}
    </div>
{% endfor %}

2. 表单提交后页面没有刷新

  • 确保表单的提交方法是 POST 并且视图中处理了 POST 请求。

3. 自定义表单字段验证

  • 如果验证失败,请确保抛出 forms.ValidationError 异常并给出合适的错误信息。

8. 参考资料

出站链接

站内链接