首页 > 解决方案 > 如何使用获取请求参数的自定义验证方法

问题描述

我有一个非常简单的表单,我正在对其进行一些验证:

def clean(self):
    cleaned_data = super().clean()

    start = cleaned_data.get("start")
    end = cleaned_data.get("end")

    if start >= end:
        raise ValidationError("start should not be greater than end.")

但我需要添加另一个验证(基于发出请求的用户)。

我试图将参数添加到 clean 方法中:

def clean(self, user):
    cleaned_data = super().clean()

    start = cleaned_data.get("start")
    end = cleaned_data.get("end")

    if start >= end:
        raise ValidationError("start should not be greater than end.")

    if not user.email.endswith("@example.com"):
        raise ValidationError("blah...")

不幸的是,我无法在视图中使用参数调用 is_valid():

if form.is_valid(request.user):
   ....

我收到以下错误消息:

is_valid() 接受 1 个位置参数,但给出了 2 个

我还尝试在表单中添加一个新方法:

def validate_email(self, user):
    if not user.email.endswith("@example.com")::
        raise ValidationError("blah...")

并从视图中调用它:

if form.is_valid() and form.validate_email(request.user):
    obj = form.save(commit=False)
    obj.created_by = request.user
    obj.save()

在这种情况下,异常真的会被抛出并使应用程序崩溃。

我的目标是:

实现自定义验证的正确方法是什么?

标签: pythondjangodjango-forms

解决方案


我会创建一个简单的 mixin 类

class FormContextMixin:
    def __init__(self, *args, **kwargs):
        self.context = kwargs.pop("context", {})
        super().__init__(*args, **kwargs)

然后将FormContextMixin类与您的表单类一起使用

class AlbumModelForm(FormContextMixin, forms.ModelForm):
    def clean(self):
        user = self.context["request"].user
        # doe something with `user`

    class Meta:
        fields = '__all__'
        model = Album

因此,您可以使用任意数据将表单初始化为

form = AlbumModelForm(request.POST, context={"request": request})

推荐阅读