使用电子邮件验证并导致路由问题

时间:2012-06-28 08:27:17

标签: django django-authentication django-registration django-login

我正在尝试通过电子邮件而非用户名验证用户。

我正在使用django-userena并使用其文档等。我几乎设置了所需的任何东西。例如:USERENA_WITHOUT_USERNAMES = True在其设置中等等。

但是在注册之后,我遇到了一系列问题。比如尝试在URL中传递我的用户名以进行身份​​验证,注册完成问题等等。

我更改了一些需要用户名作为参数的视图函数,但这种方法既没有解决我的问题,也没有正确的(也许是安全的)方法。

例如,通过路由到此网址http://127.0.0.1:8000/accounts/signup/complete/(在$ ./manage.py check_permissions之后),我收到此错误:

global name 'username' is not defined
/userena/views.py in directto_user_template
user = get_object_or_404(User, username_iexact=username)

我有什么遗漏吗?

更新 这是我得到的输出:

  

渲染时捕获NoReverseMatch:反向'userena_activate'   带参数'('xyz@xyz.com',   '70b60d1d97015e03ba8d57f31e4c7ff14d6ab753')'和关键字参数   找不到“{}”。

很明显,userena尝试使用URL作为用户名发送电子邮件:

  

userena / templates / userena / emails / activation_email_message.txt,第8行的错误

1   {% load i18n %}{% autoescape off %}
2   {% if not without_usernames %}{% blocktrans with user.username as username %}Dear {{ username }},{% endblocktrans %}
3   {% endif %}
4   {% blocktrans with site.name as site %}Thank you for signing up at {{ site }}.{% endblocktrans %}
5   
6   {% trans "To activate your account you should click on the link below:" %}
7   
8   {{ protocol }}://{{ site.domain }}{% url userena_activate user.username activation_key %}
9   
10  {% trans "Thanks for using our site!" %}
11  
12  {% trans "Sincerely" %},
13  {{ site.name }}
14  {% endautoescape %}

更新2: 好的 。通过阅读SignupFormOnlyEmail类表单的源代码,它表示会自动生成随机用户名。

class SignupFormOnlyEmail(SignupForm):
    """
    Form for creating a new user account but not needing a username.

    This form is an adaptation of :class:`SignupForm`. It's used when
    ``USERENA_WITHOUT_USERNAME`` setting is set to ``True``. And thus the user
    is not asked to supply an username, but one is generated for them. The user
    can than keep sign in by using their email.

    """
    def __init__(self, *args, **kwargs):
        super(SignupFormOnlyEmail, self).__init__(*args, **kwargs)
        del self.fields['username']

    def save(self):
        """ Generate a random username before falling back to parent signup form """
        while True:
            username = sha_constructor(str(random.random())).hexdigest()[:5]
            try:
                User.objects.get(username__iexact=username)
            except User.DoesNotExist: break

        self.cleaned_data['username'] = username
        return super(SignupFormOnlyEmail, self).save()

更新:

我终于解决了这个问题。我还在django-email-as-username旁边使用了django-userena。这是我的问题的原因。显然,他们有一些冲突。看完

2 个答案:

答案 0 :(得分:2)

您已使用关键字参数(userena_activateusername)定义了网址activation_key,但您只需使用参数调用它,将模板更改为关键字参数:

{% url userena_activate username=user.username activation_key=activation_key %}

由于评论而编辑:

我不确定我是否能够理解你的问题,但我认为其他地方存在问题。您的错误消息说:

Caught NoReverseMatch while rendering: Reverse for 'userena_activate' with arguments '('xyz@xyz.com', '70b60d1d97015e03ba8d57f31e4c7ff14d6ab753')' and keyword arguments '{}' not found.

似乎你将有效的参数传递给函数,但是你以错误的方式传递它们。 urls.py中的网址路由以预期kwargs的方式定义,但您只传递args,这与其定义不匹配。这就是您收到此错误消息的原因。简单的传递参数为kwargs(这意味着每个参数的传递名称和值如上所示)。

urls.py参数和关键字参数之间的区别:

url(r'^(?P<username>[\.\w]+)/activate/(?P<activation_key>\w+)/$', userena_views.activate, name='userena_activate'),
         ^ this is _keyword argument_ 'username', expects value with argument value AND name

url(r'^page/(.*)/$', userena_views.ProfileListView.as_view(), name='userena_profile_list_paginated'),
            ^ this is argument, expects only value, not argument name

答案 1 :(得分:0)

使用电子邮件地址作为用户名(有效)的一个非常简单的替代方法是django-easy-userena - 这是一个向上兼容的Userena分支,它增加了一些不错的功能:

  • 使用电子邮件地址作为有效的用户ID - 生成随机数字 表单和确认电子邮件中隐藏的用户名
  • 更少的依赖关系 - 不需要django-guardian或简单缩略图
  • 服务条款协议字段内置,显示为复选框

我已经有了很好的结果 - 出于某种原因安装是手动的(将userena dir复制到site-packages)但是没有麻烦。

我喜欢整体的Userena方法,但easy-userena更适合我的需要。

相关问题