使用django-registration自动生成Django用户名

时间:2011-08-12 23:28:19

标签: django django-registration

我正在尝试提供用户注册表单,而无需手动输入用户名。我设置了一个身份验证后端,以便用户可以使用电子邮件地址进行身份验证,这是有效的,因为我可以使用Django管理员用户登录。我的想法是我的应用程序将创建一个电子邮件地址的SHA1哈希值存储为Django用户名,用户永远不会看到这个。

我从注册html模板中删除了用户名字段,但我不确定应该以编程方式生成用户名的方式或位置。我认为它应该在RegistrationForm的clean_username方法中,但是当我使用没有username字段的模板时,不会调用该方法。

任何帮助肯定会受到赞赏。

2 个答案:

答案 0 :(得分:1)

我得到了它的工作。我不得不直接修改注册的视图方法和默认注册后端。我希望在我自己的代码中进行这些更改,并且仍在努力进行这些更改,但这确实有效。

我是这样做的:

  1. 创建一个名为RegBackend的自定义注册后端,根据电子邮件地址生成sha1哈希,然后将hexdigest存储为用户名,最后返回User对象。

  2. 将urls.py中的地址注册到我在步骤1中创建的新RegBackend

  3. 修改了django-registration的视图注册方法,以创建一个随机用户名,以便表单验证,但我永远不会保留随机用户名。我复制了request.POST字典并将此随机用户名设置为名为data ['username']的副本字典键之一。然后我在创建form_class的实例时使用数据变量。在表单上调用is_valid()将返回false,因为我从模板中删除了用户名,但Django需要用户名进行注册,因此我需要提供某些内容

  4. 我没有对随机用户名使用sha1哈希值,因为Django用户名长度只能是30个字符,而sha1哈希值是40.奇怪的是,自定义注册后端没有抱怨并且可以存储sha1哈希值,但由于提交时的长度,表格会产生错误。

    _ init _。py (我复制了现有的DefaultBackend并使用SHA1部分进行了修改)

    from django.conf import settings
    from django.contrib.sites.models import RequestSite
    from django.contrib.sites.models import Site
    
    from registration import signals
    from registration.forms import RegistrationForm
    from registration.models import RegistrationProfile
    
    import hashlib
    
    class RegBackend(object):
    
    def register(self, request, **kwargs):
    
    hash_user = hashlib.sha1()
    hash_user.update(kwargs['email'])
    
        username, email, password = hash_user.hexdigest(), kwargs['email'], kwargs['password1']
    
        if Site._meta.installed:
            site = Site.objects.get_current()
        else:
            site = RequestSite(request)
        new_user = RegistrationProfile.objects.create_inactive_user(username, email,
                                                                    password, site)
        signals.user_registered.send(sender=self.__class__,
                                     user=new_user,
                                     request=request)
        return new_user
    
        #omitted other code from DefaultBackend that I didn't modify
    

    <强> urls.py

    url(r'^register/$', register, {'backend': 'registration.backends.default.RegBackend', 'form_class': UserRegistrationForm}, name='registration_register'),
    

    registration / views.py

    def register(request, backend, success_url=None, form_class=None,
                 disallowed_url='registration_disallowed',
                 template_name='registration/registration_form.html',
                 extra_context=None):
    
        backend = get_backend(backend)
        if not backend.registration_allowed(request):
            return redirect(disallowed_url)
        if form_class is None:
            form_class = backend.get_form_class(request)
    
        if request.method == 'POST':
            # I added the next two lines
            data = request.POST.copy()
            data['username'] = ''.join([choice(letters) for i in xrange(30)])
            form = form_class(data=data, files=request.FILES)
            if form.is_valid():
                new_user = backend.register(request, **form.cleaned_data)
                if success_url is None:
                    to, args, kwargs = backend.post_registration_redirect(request, new_user)
                    return redirect(to, *args, **kwargs)
                else:
                    return redirect(success_url)
    
        else:
            form = form_class()
    
        if extra_context is None:
            extra_context = {}
        context = RequestContext(request)
        for key, value in extra_context.items():
            context[key] = callable(value) and value() or value
    
        return render_to_response(template_name,
                                  {'form': form},
                                  context_instance=context)
    

答案 1 :(得分:0)

您可能正在考虑继承RegistrationForm,然后重写clean方法(我不喜欢这样,因为clean方法有明确的目的,请参阅https://docs.djangoproject.com/en/dev/topics/forms/modelforms/#overriding-the-clean-method)< / p>

更简单的解决方案可能是提示用户输入他们的电子邮件地址,然后处理该表单以生成您的用户名,并将该值作为额外的上下文传递给register视图。然后,不是删除用户名字段,而是为其分配散列值并将其隐藏在模板中。这样,你就不必乱用django-registration本身了。

有关extra_context参数的详细信息,请参阅https://bitbucket.org/ubernostrum/django-registration/src/fad7080fe769/registration/views.py