百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术文章 > 正文

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

myzbx 2024-12-22 19:43 23 浏览

当然,除了上述介绍的内容外,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='example@example.com')
    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() 方法发送邮件,并跳转到完成页面。

相关推荐

如何用5分钟开发一个 Webpack Loader?

嗨,我是勾勾。今天分享的内容是如何开发一个简单的WebpackLoader,希望通过这个过程能够让你Get到WebpackLoader的工作原理与机制。Loader作为Webpack...

前端——CORS跨域请求的限制与解决

node中设置允许跨域如果需要设置多个域允许跨域,可以根据req请求的地址进行写入不同的header;consthttp=require('http')http.cre...

5分钟看懂的WebAssembly入门指南(webassembly开发)

子肃阿里开发者2023-06-2009:01发表于浙江阿里妹导读本文是一篇WebAssembly的入门文章,从理论介绍到实战方面有全面的讲述。历史进程由于javascript的动态类型特性...

刚刚发布!Claude 4连续工作7小时,比Cursor、Copilot还猛?

你见过不吃不喝、连续工作7小时的“程序员”吗?Anthropic最新发布的Claude4,不只是AI,更像是你团队里的CTO。一、什么是Claude4?别急,这不是你熟悉的GPT“亲戚”202...

JS对象判空的几种方式,你真的会了吗?

前言:为什么空对象检测如此重要?在开发中我们经常会遇到这样的场景:if(isEmpty(userInfo)){//跳转登录页}四种主流检测方案对比方案一:Object.keys()基础版fun...

密码被破译,行踪被美军全程掌握,日本海军军神命丧太平洋

【军武次位面】FriedrichLau一.突袭1941年12月7日,伴随着日军偷袭美军位于珍珠港的基地,美国也终于卷入了这场绵延全球的战火之中。为了报复日军这一行动,美军随后打出了一套组合拳,除了在太...

提示词技术详解(2)——零样本提示词

一、零样本提示(Zero-Shot)是一种会起到作用的办法。首先让模型重写提示词,然后把重写后的提示词再发给模型,以期提升回答效果。论文给出的提示词如下,仅供参考。给定一位用户的以下文字,提取其中不带...

这些流行饮料的中文名称,你会说吗?

[Photo/Pexels]Summerisinfullswing,andtheweatherishot!Tohelpyoucooldown,coldandrefre...

密码被破译多可怕?被美军全程盯梢,日本海军军神命丧太平洋

【军武次位面】FriedrichLau一.突袭1941年12月7日,伴随着日军偷袭美军位于珍珠港的基地,美国也终于卷入了这场绵延全球的战火之中。为了报复日军这一行动,美军随后打出了一套组合拳,除了在太...

一课译词:刀子嘴(刀子嘴是什么)

你身边一定有一些人,他们的言语总是那么尖锐、刺耳,但内心却又格外善良柔软,了解他们的人都知道,他们其实只是“刀子嘴,豆腐心”。“刀子嘴”,形容人说话十分刻薄(speaksarcasticallya...

捷克插画家柯薇塔·巴可维斯卡逝世,曾为《灰姑娘》绘制插图

柯瑞塔·巴可维斯卡。(图源:捷克共和国文化部)据捷克多家媒体消息,当地时间2月6日,捷克插画家柯薇塔·巴可维斯卡逝世,享年94岁。该消息经由她的儿子斯特潘·格里格(StěpánGrygar)证实。柯...

网络“匿名提问箱”成年轻人社交新宠 为何这么火?

网络“匿名提问箱”成为年轻人社交新宠“来自陌生人的关心”为什么这么火?“年度歌单里排名第一的是哪首歌?”“未来十年你的人生规划?”“有没有被甩过?”最近,这种别人能够匿名向自己提问的“提问箱”越来越得...

美国要开始搞6G了?专家:关键技术仍在摸索

2月21日,美国总统特朗普发推特“我希望5G乃至6G早日在美国落地”。日前,美国联邦通信委员会朝着特朗普的指示迈出了第一步,决定开放95千兆赫到3太赫兹频段,供6G实验使用。纽约大学教授泰德·拉帕波特...

常见的连续型随机变量(1)(连续型随机变量的定义与性质)

1.均匀分布在概率论和统计学中,均匀分布也叫矩形分布,它是对称概率分布,在相同长度间隔的分布概率是等可能的。均匀分布由两个参数a和b定义,它们是数轴上的最小值和最大值,通常缩写为U(a,b)。统计...

身高表上的-2SD、-1SD、中位数.....都是啥?和百分位有关系吗?

上周日晚,小编正气呼呼地和娃上演“作业拉锯战”时,“叮”的一声,一条微信发了过来。无独有偶,第二天又有朋友发来门诊记录,不知道SD什么意思。从家长应用的角度来看,无需太纠结,根据个人习惯选择即可。从生...