关键词

详解Django的 clean() 函数:定义表单字段的清理行为

Django clean()函数的作用与使用方法攻略

在 Django 中,clean() 函数是一个非常有用的方法,可以帮助我们校验表单提交的数据并返回经过校验后的数据。

作用

clean() 函数作用是在 Django Form 表单数据进行提交前进行校验,并将校验过后的数据返回。

校验的过程中,我们可以对该数据进行一些操作,比如格式化数据、消除不必要的数据、检查数据是否符合要求等等。在校验时,clean() 函数的一个重要特征是,如果该数据不符合规范,我们可以抛出一个错误,这样表单就不会被提交到后台。

使用方法

Django 的 clean() 一般是在 Django Form 中定义。我们首先要在 forms.py 文件中定义一个继承 forms.Form 的类,然后在该类中写入需要校验的字段,并在每个字段后面定义一个 clean_ 前缀的方法,这个方法应该返回一个经过校验过后的值。

下面是一个简单的例子,我们来看一下 clean() 函数是如何校验数据并返回校验后的数据的:

from django import forms
from .models import Book


class BookForm(forms.Form):
    title = forms.CharField(max_length=100)
    author = forms.CharField(max_length=100)
    published_date = forms.DateField()

    def clean_title(self):
        title = self.cleaned_data['title']
        if Book.objects.filter(title=title).exists():
            raise forms.ValidationError('This title has already been used.')
        return title

    def clean_author(self):
        author = self.cleaned_data['author']
        if len(author) < 3:
            raise forms.ValidationError('Author name must be at least 3 characters long.')
        return author

    def clean(self):
        cleaned_data = super().clean()
        published_date = cleaned_data.get('published_date')
        if published_date and published_date > timezone.now().date():
            raise forms.ValidationError('The published date cannot be in the future.')
        return cleaned_data

以上代码演示了如何定义一个简单的 Django 表单,该表单有三个校验字段,即 titleauthorpublished_date。前两个字段自定义了校验方法,published_date 字段则使用了默认的校验方式。

在上述代码中,clean_titleclean_author 方法自定义了数据的校验方式。每个方法都会返回一个值,如果数据不符合规范则抛出一个错误。使用这种方式能够更好地控制数据的校验和处理。

clean() 方法用于校验整个表单,它也是在 cleaned_data 中返回校验后的数据。在这种情况下,我们使用了 super().clean() 方法来检验并返回经过校验的数据,然后检查 published_date 是否被设置为未来的日期。如果是,则抛出一个 ValidationError。如果没有错误,则返回所有校验过后的数据。

实例

下面给出两个实例来说明 clean() 函数的使用方法。

1. 校验注册表单中的密码是否匹配

在这个例子中,我们来考虑一个注册表单。这个表单中有两个字段,分别是密码和确认密码。我们需要校验这两个字段的值是否相等。

from django import forms

class RegisterForm(forms.Form):
    username = forms.CharField(max_length=100)
    email = forms.EmailField(max_length=100)
    password = forms.CharField(widget=forms.PasswordInput())
    confirm_password = forms.CharField(widget=forms.PasswordInput())

    def clean(self):
        cleaned_data = super().clean()
        password = cleaned_data.get("password")
        confirm_password = cleaned_data.get("confirm_password")

        if password != confirm_password:
            raise forms.ValidationError(
                "The two password fields must match."
            )

        return cleaned_data

在上述代码中,我们定义了一个继承自 forms.Form 的类 RegisterForm,其中有 passwordconfirm_password 两个字段。我们使用了 widget=forms.PasswordInput() 来隐藏输入密码的字符。接着,我们定义了一个名为 clean() 的内置校验函数。在此函数中,我们首先调用 super().clean() 函数来获取经过基础校验后的数据。然后,我们检查 passwordconfirm_password 是否相等,如果不相等,则抛出错误,系统就会抵制这个表单提交。

2. 校验注册表单中的用户名是否已存在

这个例子和上面的例子比较类似,我们考虑一个注册表单中的用户名校验。假设我们要保证用户名不重复。

from django import forms
from .models import User

class RegisterForm(forms.Form):
    username = forms.CharField(max_length=100)
    email = forms.EmailField(max_length=100)
    password = forms.CharField(widget=forms.PasswordInput())
    confirm_password = forms.CharField(widget=forms.PasswordInput())

    def clean_username(self):
        username = self.cleaned_data['username']
        if User.objects.filter(username=username).exists():
            raise forms.ValidationError('This username has been taken.')
        return username

    def clean(self):
        cleaned_data = super().clean()
        password = cleaned_data.get("password")
        confirm_password = cleaned_data.get("confirm_password")

        if password != confirm_password:
            raise forms.ValidationError(
                "The two password fields must match."
            )

        return cleaned_data

上面的代码中,我们调用了 User.objects.filter(username=username).exists() 方法检查是否存在了这个用户名。如果存在则抛出一个错误。接着,我们使用 clean() 函数来校验密码是否匹配,如果不匹配则也抛出一个错误。

本文链接:http://task.lmcjl.com/news/16158.html

展开阅读全文