天天看点

django框架的表单form的理解和用法-1

作者:不易9093

当然,除了上述介绍的内容外,Django 的表单系统还有许多其它功能和技巧。以下是一些值得注意的事项:

  1. CSRF 保护

在 Django 中,默认启用 CSRF 保护机制,以防止跨站请求伪造攻击。当使用 POST 方法提交表单时,Django 会自动生成一个随机的 CSRF 标记,该标记必须与表单数据一起提交才能被接受。要在表单中添加 CSRF 标记,可以使用 {% csrf_token %} 模板标签。

<form method="post">
    {% csrf_token %}
    <!-- 表单字段 -->
</form>           
  1. 验证错误信息

在表单验证失败时,Django 会将错误信息存储在表单对象的 errors 属性中,并使用模板标签 {% for error in form.field.errors %} 来逐个显示错误信息。如果想要显示所有错误信息,可以使用 {% for error in form.non_field_errors %}。

  1. 自定义错误信息

如果需要自定义验证器的错误信息,则可以在表单类中设置相应的 error_messages 字典。例如,我们可以在联系表单中添加自定义错误信息。

from django import forms

class ContactForm(forms.Form):
    subject = forms.CharField(max_length=100, error_messages={
        'required': 'Please enter a subject.'
    })
    message = forms.CharField(error_messages={
        'required': 'Please enter a message.'
    })
    sender = forms.EmailField(error_messages={
        'required': 'Please enter a valid email address.'
    })           

在上述示例中,我们使用 error_messages 属性为每个字段自定义了错误信息。这些错误信息将覆盖默认的错误信息。

除了上述介绍的基本用法和高级功能外,Django 的表单系统还有一些其它特性需要注意。

  1. 带初始值的表单

在 Django 表单系统中,可以通过 initial 属性为表单字段提供初始值。例如,我们可以在联系表单中添加默认主题和发送者。

from django import forms

class ContactForm(forms.Form):
    subject = forms.CharField(max_length=100, initial='A default subject')
    message = forms.CharField(initial='A default message')
    sender = forms.EmailField(initial='[email protected]')
    cc_myself = forms.BooleanField(required=False)           

在上述示例中,我们使用 initial 属性为 subject、message 和 sender 字段提供了默认值。这些值将在表单初始化时显示在相应的文本框或复选框中。

  1. 额外的数据

在处理表单数据时,有时需要额外的数据来辅助处理。Django 的表单系统提供了 extra_data 属性来存储这些数据。例如,我们可以在联系表单中添加一个附件上传字段,并将上传的文件保存到服务器上。

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)
    attachment = forms.FileField(required=False)

    extra_data = {}

    def handle_attachment(self):
        if 'attachment' in self.files:
            file = self.files['attachment']
            filename = file.name
            content = file.read()
            self.extra_data['attachment_content'] = content
            self.extra_data['attachment_filename'] = filename

    def clean(self):
        self.handle_attachment()
        return super().clean()           

在上述示例中,我们定义了一个名为 attachment 的文件上传字段,并使用 extra_data 属性存储上传的文件内容和文件名。然后,在 clean() 方法中调用 handle_attachment() 方法来处理上传的文件,并将结果存储到 extra_data 属性中。

  1. 表单分页

如果一个表单包含大量的字段或数据,可以将其分成多个页面进行填写,以提高用户的体验。Django 的表单系统提供了 FormWizard 类来实现表单分页。例如,我们可以将联系表单分成两个页面。

from django import forms
from django.core.files.uploadedfile import InMemoryUploadedFile
from io import BytesIO
from wizard.forms import ContactFormStep1, ContactFormStep2
from wizard.models import Contact

class ContactFormWizard(SessionWizardView):
    template_name = 'wizard/contact_form.html'

    form_list = [
        ('step1', ContactFormStep1),
        ('step2', ContactFormStep2)
    ]

    def done(self, form_list, **kwargs):
        # 记录联系信息并发送邮件
        contact = Contact.objects.create(
            subject=form_list[0].cleaned_data['subject'],
            message=form_list[1].cleaned_data['message'],
            sender=form_list[2].cleaned_data['sender']
        )

        if 'attachment' in form_list[1].files:
            file = form_list[1].files['attachment']
            filename = file.name
            content = file.read()
            attachment = InMemoryUploadedFile(
                BytesIO(content),
                None,
                filename,
                'application/octet-stream',
                len(content),
                None
            )
            contact.attachment.save(filename, attachment)

        contact.send_email()
        return render(self.request, 'wizard/done.html')           

在上述示例中,我们定义了一个名为 ContactFormWizard 的表单向导,并指定了两个表单步骤。在处理完最后一个步骤的数据后,我们创建了一个名为 Contact 的模型实例,并将表单数据存储到该实例中。然后,如果有附件上传,我们将其保存到服务器并记录在模型实例中。最后,我们调用模型实例的 send_email() 方法发送邮件,并跳转到完成页面。