在Django表单中获取请求数据

61 投票
6 回答
78988 浏览
提问于 2025-04-15 13:15

在表单类中获取请求的用户数据是否可能?我想要清理一个电子邮件地址,以确保它是唯一的,但如果这个电子邮件地址是当前用户的,那就应该通过验证。

我现在的做法在创建新用户时效果很好,但如果我想编辑一个用户,就会遇到问题,因为他们的电子邮件地址不通过验证,系统提示这个地址已经被占用。如果我能通过 request.user.email 来检查这个地址是否是他们的,那我就能解决这个问题,但我不太确定该怎么做。

class editUserForm(forms.Form):
    email_address = forms.EmailField(widget=forms.TextInput(attrs={'class':'required'}))

    def clean_email_address(self):
        this_email = self.cleaned_data['email_address']
        test = UserProfiles.objects.filter(email = this_email)
        if len(test)>0:
            raise ValidationError("A user with that email already exists.")
        else:
            return this_email

6 个回答

5

告诉你一个事情,使用Django 1.4版本和基于类的通用创建视图(CreateView)和更新视图(UpdateView)时,每个模型表单都会有一个自带的实例(self.instance)。这个实例让你可以比较用户提交的电子邮件和当前用户的电子邮件。

下面是一个代码示例,使用了混入(mixin)。

class EmailUniqueMixin(object):
    """
    Ensure each User's email is unique
    on the form level
    """
    def clean_email(self):
        email = self.cleaned_data['email']
        existing_email = User.objects.filter(email=email).exclude(pk=self.instance.id)
        if existing_email:
            raise forms.ValidationError('That email address already exists')
        else:
            return email
43

这里是如何在使用通用视图时获取表单中的用户的方法:

在视图中,使用 get_form_kwargsrequest.user 传递给表单:

class SampleView(View):
    def get_form_kwargs(self):
        kwargs = super(SampleView, self).get_form_kwargs()
        kwargs['user'] = self.request.user
        return kwargs

在表单中,你可以通过 __init__ 函数接收到 user

class SampleForm(Form):
    def __init__(self, user, *args, **kwargs):
        super(SampleForm, self).__init__(*args, **kwargs)
        self.user = user
79

正如ars和Diarmuid所提到的,你可以把request.user传入你的表单中,并用它来验证邮箱。不过,Diarmuid的代码是错的。正确的代码应该是:

from django import forms

class UserForm(forms.Form):
    email_address = forms.EmailField(
        widget=forms.TextInput(
            attrs={
                'class': 'required'
            }
        )
    )

    def __init__(self, *args, **kwargs):
        self.user = kwargs.pop('user', None)
        super(UserForm, self).__init__(*args, **kwargs)

    def clean_email_address(self):
        email = self.cleaned_data.get('email_address')

        if self.user and self.user.email == email:
            return email

        if UserProfile.objects.filter(email=email).count():
            raise forms.ValidationError(
                u'That email address already exists.'
            )

        return email

然后,在你的视图中,你可以这样使用:

def someview(request):
    if request.method == 'POST':
        form = UserForm(request.POST, user=request.user)
        if form.is_valid():
            # Do something with the data
            pass
    else:
        form = UserForm(user=request.user)
    # Rest of your view follows

注意,你应该把request.POST作为关键字参数传入,因为你的构造函数期望'user'作为第一个位置参数。

这样做的话,你需要把user作为关键字参数传入。你可以把request.POST作为位置参数传入,也可以作为关键字参数传入(通过data=request.POST)。

撰写回答