【问题标题】:get request data in Django form以 Django 形式获取请求数据
【发布时间】:2010-11-15 05:28:07
【问题描述】:

是否可以在表单类中获取 request.user 数据?我想清理一个电子邮件地址以确保它是唯一的,但如果它是当前用户的电子邮件地址,那么它应该可以通过。

这是我目前拥有的,非常适合创建新用户,但是如果我想编辑一个用户,我会遇到他们的电子邮件无法验证的问题,因为它已经被占用了。如果我可以使用 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

【问题讨论】:

    标签: python django


    【解决方案1】:

    正如 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)传递。

    【讨论】:

    • >请注意,您应该将 request.POST 作为关键字参数传递,因为您的构造函数期望 'user' 作为第一个位置参数。这就是为什么您不应该将关键字(即可选)参数与 **kwargs 混合使用的具体原因。相反,构造函数不应该有用户,只需将其作为第一行:user = kwargs.pop('user') if 'user' in kwargs else None
    • 已经很久了,所以我不确定我的问题是否正确。我使用kwargs.get('user', None) 来获取用户,但在下一行中,它将TypeError 提升为__init__() got an unexpected keyword argument 'user',我知道弹出获取并删除user,但我不知道为什么我不能保留@987654331 @in kwargs。
    • @shellbye:表单的默认 __init__(...) 不期望 user 参数;这就是我使用kwargs.pop(...) 的原因。你有什么理由想让用户留在kwargs吗?
    • @elo80ka 不,我不想让用户留在kwargs,我只是不小心使用了get 并遇到了那个错误。我已经切换到pop,但不知道为什么。根据你说的,我查了源码,发现Form默认的__init__(...)里面没有kwargs,所以我们要pop出自定义的user,对吧?
    【解决方案2】:

    以下是使用通用视图时在表单中获取用户的方法:

    在视图中,使用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
    

    【讨论】:

    • 我实际上更喜欢这种方式,但你应该在调用构造函数之前从 kwargs 中删除用户.. 类似self.user = kwargs.pop('user')
    【解决方案3】:

    您知道,使用 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
    

    【讨论】:

      【解决方案4】:

      我不知道。处理此问题的一种方法是让您的 Form 类的 __init__ 采用可选的电子邮件参数,它可以将其存储为属性。如果在表单创建时提供,它可以在验证期间使用它来进行您感兴趣的比较。

      【讨论】:

        【解决方案5】:

        在视图中实例化表单时,可以通过参数传递一个实例,在表单内部使用。

        form = YourModelForm(request.POST, instance=request.user)
        

        在表单中,你必须这样访问:

         if *self.instance.email* == email:
            return email
        

        【讨论】:

          【解决方案6】:

          我们可以使用get_form方法:

          class SampleView(View):
              def get_form(self, request, *args, **kwargs):
                  form = super().get_form(request, *args, **kwargs)
                  form.request_user = request.user
                  return form
          
          class SampleForm(Form):
              def clean_email_address(self):
                  email = self.cleaned_data['email_address']
          
                  if self.request_user and self.request_user.email==email:
          

          【讨论】:

            猜你喜欢
            • 2022-08-06
            • 1970-01-01
            • 2017-08-27
            • 2011-05-08
            • 1970-01-01
            • 2012-05-28
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多