Goal

我需要使用户能够访问表单以进行验证(即,通过self.request.user)

Approach Taken

我在我的视图中使用get_form_kwargs()函数来使请求可用于我的表单(如此处所建议的:Very similar problem).

Problem

尽管遵循了上面链接的StackOverflow答案中概述的步骤,但我还是收到了错误'NoneType' object has no attribute 'user'

代码

Views.py

class MemberDetailView(LoginRequiredMixin, generic.DetailView):
    """View class for member profile page"""
    model = User
    context_object_name = 'user'

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs,)
        context['form'] = JoinCommunityForm()
        return context
    
class JoinCommunityFormView(FormView):
    """View class for join code for users to join communities"""
    form_class = JoinCommunityForm

    def get_form_kwargs(self, *args, **kwargs):
        form_kwargs = super().get_form_kwargs(*args, **kwargs)
        form_kwargs['request'] = self.request
        return form_kwargs

    def post(self, request, *args, **kwargs):
        """posts the request to join community only if user is logged in"""
        if not request.user.is_authenticated:
            return HttpResponseForbidden
        return super().post(request, *args, **kwargs)
    
class MemberDashboardView(View):
    """View class to bring together the MemberDetailView and the JoinCommunityFormView"""
    def get(self, request, *args, **kwargs):
        view = MemberDetailView.as_view()
        return view(request, *args, **kwargs)
    
    def post(self, request, *args, **kwargs):
        view = JoinCommunityFormView.as_view()
        form = JoinCommunityForm(request.POST)
        if form.is_valid():

Forms.py

**引发错误的行是100**

from communities.models import Community, UserRoleWithinCommunity

class JoinCommunityForm(forms.Form):
    pin = forms.RegexField(
                           '^[A-HJ-NP-Z1-9]$',
                           max_length=6, 
                           label='',
                           widget=forms.TextInput(attrs={
                               'oninput': 'this.value = this.value.toUpperCase()'
                                                        }
                                                  )
                           )

    def __init__(self, *args, **kwargs):
        self.request = kwargs.pop('request', None)
        super(JoinCommunityForm, self).__init__(*args, **kwargs)
    
    def clean(self):
        cleaned_data = super().clean()
        pin = self.cleaned_data['pin']
        test_join_code = f'{pin}'
        if Community.objects.filter(join_code=test_join_code).exists():
            # Make sure user is not already a member of the community
            communityToJoin = Community.objects.get(join_code=test_join_code)
            if UserRoleWithinCommunity.objects.filter(
                community=communityToJoin,
                user=self.request.user
            ).exists():
                raise forms.ValidationError("You're already a member 
                                             of that Community")
            else:
                return cleaned_data
        else:
            raise forms.ValidationError("Join code is incorrect")

Edit 1:

我try 了Willem建议的方法,但仍然遇到相同的错误'NoneType' object has no attribute 'user',即追溯到我的表单中需要通过self.request.user访问用户的那一行.

所有Forms.py个代码保持与上面的完全相同.我的Views.py代码更改如下(我现在只有一个视图,而不是馈送到另一个视图的两个视图(表单视图和详细信息视图)):

Views.py

# all necessary import statements

class MemberDetailView(
        LoginRequiredMixin, FormMixin,
        generic.DetailView, ProcessFormView
    ):
    """View class for member profile page"""
    model = User
    context_object_name = 'user'
    form_class = JoinCommunityForm
    success_url = '#communities-card'
    template_name = 'home/terpuser_detail.html'

    def get_queryset(self, *args, **kwargs):
        qs = super().get_queryset(*args, **kwargs)
        if not self.request.user.is_superuser:
            qs = qs.filter(pk=self.request.user.pk)
        return qs

    def get_context_data(self, **kwargs):
        context = super().get_context_data(
            **kwargs,
            demo=get_object_or_404(Scenario.objects, scenario_id='demo'),
            today=date.today(),
        )
        return context
    
    def form_valid(self, form):
        # this is where I put my code to create a new Community 
        # membership object
        return super().form_valid(self, form)

Urls.py

from django.urls import path
from . import views

urlpatterns = [
    path('member/<slug:slug>/', views.MemberDetailView.as_view(), name='member-detail')
]

错误消息

  • 请求方式:POST
  • 请求URL:http://127.0.0.1:8000/member/tron/
  • Django版本:4.1.5
  • 异常类型:AttributeError
  • 异常值:‘NoneType’对象没有属性‘User’
  • 异常位置:../projDir/home/Forms.py,第53行,CLEAN中
  • 提出时间:home.views.MemberDetailView
  • Python可执行文件:../projDir/django-terp-venv/bin/python
  • Python版本:3.8.2

推荐答案

似乎我需要使用Form类的__init__方法获取当前用户(不仅仅是request).以下是最终正常运行的Views.pyForms.py代码:

Views.py

# all necessary import statements

class MemberDetailView(
        LoginRequiredMixin, FormMixin,
        generic.DetailView, ProcessFormView
    ):
    """View class for member profile page"""
    model = User
    context_object_name = 'user'
    form_class = JoinCommunityForm
    success_url = '#communities-card'
    template_name = 'home/terpuser_detail.html'

    def get_queryset(self, *args, **kwargs):
        qs = super().get_queryset(*args, **kwargs)
        if not self.request.user.is_superuser:
            qs = qs.filter(pk=self.request.user.pk)
        return qs

    def get_context_data(self, **kwargs):
        context = super().get_context_data(
            **kwargs,
            demo=get_object_or_404(Scenario.objects, scenario_id='demo'),
            today=date.today(),
        )
        return context
    
    def form_valid(self, form):
        # this is where I put my code to create a new Community membership object
        return super().form_valid(self, form)

Forms.py

最终解决我问题的一行是形式类的__init__方法:self.user = self.request.user.然后,我在表单类的clean方法中调用self.user,而不是self.request.user

from communities.models import Community, UserRoleWithinCommunity

class JoinCommunityForm(forms.Form):
    pin = forms.RegexField(
                           '^[A-HJ-NP-Z1-9]$',
                           max_length=6, 
                           label='',
                           widget=forms.TextInput(attrs={
                               'oninput': 'this.value = this.value.toUpperCase()'
                                                        }
                                                  )
                           )

    def __init__(self, *args, **kwargs):
        self.request = kwargs.pop('request', None) # instantiate request kwarg as Willem suggests
        self.user = self.request.user # get user, this was key to resolving error
        super(JoinCommunityForm, self).__init__(*args, **kwargs)
    
    def clean(self):
        cleaned_data = super().clean()
        pin = self.cleaned_data['pin']
        test_join_code = f'{pin}'
        if Community.objects.filter(join_code=test_join_code).exists():
            # Make sure user is not already a member of the community
            communityToJoin = Community.objects.get(join_code=test_join_code)
            if UserRoleWithinCommunity.objects.filter(
                community=communityToJoin,
                user=self.user # here I call self.user instead of self.request.user
            ).exists():
                raise forms.ValidationError("You're already a member 
                                             of that Community")
            else:
                return cleaned_data
        else:
            raise forms.ValidationError("Join code is incorrect")

Django相关问答推荐

Django动态页面.为什么我的代码不工作?

构造一个定制字符串(实体、年份和字母数字的组合)作为Django中的Postgres数据库的主键是否明智?

AttributeError:';ManyToOneRel&39;对象没有属性';attname';

如何在Django CMS中更新上下文

新的 Django 开发人员无法在网站上显示Hello World,而不是默认安装成功页面

通过 OrderingFilter 过滤平均和

Django prefetch_related 与 3 个不直接相关的模型

int_list_validator在 Django 表单中不起作用

Django 表单字段必填和可选配置

查询 django 模型以找到当月最好的公司销售

Django - 站点匹配查询不存在

Django Calendar日历小部件?

ManyRelatedManager 不可迭代

如何在Django中获取一个组的所有用户?

Django:访问给定字段的 Select 元组

Django 有 SmallIntegerField 的原因是什么?

Django - 配置不当:模块django.contrib.auth.middleware

Django 用户配置文件

在 Django 中查询 top x 元素

如何获取 Django 模型字段对象的值