【问题标题】:How to request.user.is_authenticated() in views.py? Django如何在views.py中请求.user.is_authenticated()?姜戈
【发布时间】:2017-04-12 10:40:18
【问题描述】:

我正在尝试检查用户是否从我的 views.py 文件中登录。取决于用户是否登录,它应该返回不同的表单。但是 request.user.is_authenticated() 或 request.user.is_authenticated 不起作用,我总是得到 True 值。

我的看法:

def ContactsView(request):
    form_class = ContactForm_logged(request=request)
    form_class_nonlogged = ContactForm_nonlogged(request=request)

    # new logic!
    if request.method == 'POST':
        if request.user.is_authenticated():
            form = ContactForm_logged(data=request.POST, request = request)
        else:
            form = ContactForm_nonlogged(data=request.POST)

        if form.is_valid():
            contact_name = request.POST.get(
                'contact_name'
                , '')
            contact_email = request.POST.get(
                'contact_email'
                , '')
            form_content = request.POST.get('content', '')
            subjects = form.cleaned_data['subjects']
            subjects = dict(form.fields['subjects'].choices)[subjects]
            # Email the profile with the
            # contact information
            template = get_template('threeD/email/contact_template.txt')
            context = Context({
                'contact_name': contact_name,
                'subjects': subjects,
                'contact_email': contact_email,
                'form_content': form_content,
            })
            content = template.render(context)

            email = EmailMessage(
                "New message from " + contact_name,
                content,
                "Message - " + subjects + ' ',
                ['smart.3d.printing.facility@gmail.com'],
                headers={'Reply-To': contact_email}
            )
            email.send()
            messages.success(request, "Thank you for your message.")
            return redirect('/index/contacts/')

    else:
        if request.user.is_authenticated():
            form = ContactForm_logged(request=request)
        else:
            form = ContactForm_nonlogged()

    if request.user.is_authenticated():
        return render(request, 'threeD/contacts.html', {
            'form': form_class,
        })
    else:
        return render(request, 'threeD/contacts.html', {
            'form': form_class_nonlogged,
        })

还有我的两个表格:

class ContactForm_logged(forms.Form):
    contact_name = forms.CharField(required=True)
    contact_email = forms.EmailField(required=True)
    subjects = forms.ChoiceField(choices=emailsubjects)
    content = forms.CharField(
        required=True,
        widget=forms.Textarea
    )

    def __init__(self, *args, **kwargs):
        self.request = kwargs.pop("request")
        super(ContactForm_logged, self).__init__(*args, **kwargs)
        self.fields['contact_name'].label = "Your name:"

        if (self.request.user.first_name == '' or self.request.user.last_name ==''):
            self.fields['contact_name'].initial = 'Type your name here'
            self.fields['contact_name'].widget.attrs['readonly'] = False
        else:
            self.fields['contact_name'].initial = self.request.user.first_name
            self.fields['contact_name'].widget.attrs['readonly'] = True

        self.fields['contact_email'].label = "Your email:"

        if (self.request.user.profile.sdu_email == ''):
            if (self.request.user.email == ''):
                self.fields['contact_email'].initial = 'Type your email here'
                self.fields['contact_email'].widget.attrs['readonly'] = False
            else:
                self.fields['contact_email'].initial = self.request.user.email
                self.fields['contact_email'].widget.attrs['readonly'] = True
        else:
            self.fields['contact_email'].initial = self.request.user.profile.sdu_email
            self.fields['contact_email'].widget.attrs['readonly'] = True

        self.fields['content'].label = "What do you want to say?"
        self.fields['content'].initial = "Dear, Smart 3D printing facility team, I like this WEB server very much, but ..."

        self.fields['subjects'].label = "Please, select the subject of your message"


class ContactForm_nonlogged(forms.Form):
    contact_name = forms.CharField(required=True)
    contact_email = forms.EmailField(required=True)
    subjects = forms.ChoiceField(choices=emailsubjects)
    content = forms.CharField(
        required=True,
        widget=forms.Textarea
    )

    def __init__(self, *args, **kwargs):
        self.request = kwargs.pop("request")
        super(ContactForm_nonlogged, self).__init__(*args, **kwargs)
        self.fields['contact_name'].label = "Your name:"

        self.fields['contact_name'].initial = 'Type your name here'

        self.fields['contact_email'].label = "Your email:"

        self.fields['contact_email'].initial = 'Type your email here'

        self.fields['content'].label = "What do you want to say?"
        self.fields['content'].initial = "Dear, Smart 3D printing facility team, I like this WEB server very much, but ..."

        self.fields['subjects'].label = "Please, select the subject of your message"

问题是,无论我是否登录,我总是会返回 ContactForm_logged 表单。如果我没有登录,则返回 ContactForm_logged 表单我会收到错误消息,即“'AnonymousUser' 对象没有属性'first_name'”。 我在论坛上读到,如果我调用 request.user.is_authenticated() 错误,可能会发生这种情况,但我尝试了 request.user.is_authenticated() 和 request.user.is_authenticated,两者都给了我同样的错误:/

任何帮助将不胜感激!

【问题讨论】:

  • 请注意,您应该在视图中使用return render(request, 'threeD/contacts.html', {'form': form})。如果你使用表单class,那么你会在模板中得到一个空白表单,所以不会显示错误。

标签: python django authentication


【解决方案1】:

如果您使用的是 Django 1.10+,那么您应该使用属性request.user.is_authenticated

如果您使用的是 Django 1.9 或更早版本,则必须使用 request.user.is_authenticated()。在 Django 1.9 或更早版本中使用 request.user.is_authenticated 是一个错误,可能导致敏感数据泄露,因为它总是会被评估为 True

如果您使用的是正确的版本并且它返回True,则表明您确实已登录。

【讨论】:

  • 谢谢你,Alasdair,你的回答。我正在使用 Django 1.9 版本,在我的视图代码中我有 request.user.is_authenticated(),但它仍然不起作用。它总是让我返回 True 。而且我确定我没有登录,因为在我的基本模板中我正在使用 {% if user.is_authenticated %} ... {% endif %} 更改导航栏并且它没有被更改(所以我确定我是未登录),然后我正在访问 ContactsView 并从我的 request.user.is_authenticated() 获取始终为真,这会导致错误:/
  • 如果request.user.is_authenticated() 为True,那么我真的认为您已登录。如果导航栏显示您未登录,则可能是导航栏代码中的错误。
  • 如果 request.user.is_authenticated() 为 True 您确实已登录。正如 Ishan 在他的回答中所说,错误可能来自 form_class_nonlogged = ContactForm_nonlogged(request=request),而不是来自 if request.user.is_authenticated(): if陈述。您可以通过添加打印语句或查看回溯自行调试。
  • Alasdair,你将如何打印调试?对不起,我对这个话题很陌生,这就是为什么我问愚蠢的问题:D
  • 如果您使用 Django 开发服务器并将print(request.user.is_authenticated()) 添加到视图顶部,那么您将在运行python manage.py runserver 的窗口中看到结果。
【解决方案2】:

问题出在视图方法定义的第一行:

def ContactsView(request):
    form_class = ContactForm_logged(request=request)

在这里,您正在创建ContactForm_logged 类的实例。每次调用视图方法时都会执行此行。因此,无论用户是否登录,每次都会创建一个 ContactForm_logged 类的实例。此外,在ContactForm_logged 类的__init__ 方法中,您正在访问self.request.user.first_name。因此,当 ContactForm_logged 实例为未经身份验证的请求初始化时,它会引发错误:“'AnonymousUser' object has no attribute 'first_name'

【讨论】:

  • 好地方!前两行应完全删除。它们仅在return render() 行中使用,正如我在上面的评论中所说,您应该在那里使用form,而不是类。如果您稍后在代码中使用form = form_class(...) 而不是使用ContactForm_logged(...)ContactForm_nonlogged(...) 的if/else,那么使用form_class 才有意义。仅当您将未记录的表单更改为也接受 request,或者将表单 kwargs 设置为单独的步骤时,您才能执行此操作。
  • 太棒了,谢谢伊山!我在视图的开头添加了一个额外的 if 语句,例如: if request.user.is_authenticated(): form_class= ContactForm_logged(request=request) else: form_class= ContactForm_nonlogged(request=request) 并返回 form_class。它现在有效。谢谢各位大佬帮忙!!!
  • 哦,现在我看到了我的问题...谢谢@Alasdair。我已经完全删除了前两行并将我的返回更改为 'form': form,正如你上面建议的那样,它仍然可以正常工作
  • 是的@Alasdair。在render 方法调用中,应使用form 代替form_classform_class_nonlogged
猜你喜欢
  • 1970-01-01
  • 2015-03-19
  • 2018-07-16
  • 2020-08-17
  • 2021-11-08
  • 2017-08-06
  • 1970-01-01
  • 2011-01-27
  • 2016-01-06
相关资源
最近更新 更多