使用Django注册自动生成Django用户名

使用Django注册自动生成Django用户名,django,django-registration,Django,Django Registration,我正在尝试提供一个用户注册表单,而不需要手动输入用户名。我设置了一个身份验证后端,以便用户可以使用电子邮件地址进行身份验证,这是因为我可以使用Django管理员用户登录。我的想法是,我的应用程序将创建一个电子邮件地址的SHA1散列,存储为Django用户名,用户将永远看不到这一点 我从我的注册html模板中删除了用户名字段,但我不确定应该如何或在何处以编程方式生成用户名。我认为应该在RegistrationForm的clean_username方法中,但是当我使用没有username字段的模板时

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

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


任何帮助都将不胜感激。

您可能会考虑子类化
RegistrationForm
,然后重写
clean
方法(不过我不喜欢这样,因为clean方法有明确的目的,请参阅)

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


有关
extra\u context
参数的更多信息,请参阅。

。我不喜欢直接修改注册的视图方法和默认注册后端。我更愿意在自己的代码中进行这些更改,并且仍在努力进行这些更改,但这确实有效

我是这样做的:

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

  • 将url.py中的register映射到我在步骤1中创建的新RegBackend

  • 修改了django注册的view register方法,创建了一个随机用户名,以便表单进行验证,但我从不保留随机用户名。我复制了request.POST字典,并将这个随机用户名设置为副本的字典键data['username']。然后我在创建form_类的实例时使用数据变量。对表单调用is_valid()将返回false,因为我从模板中删除了用户名,但Django需要用户名进行注册,所以我需要提供一些信息

  • 我没有对随机用户名使用sha1哈希,因为Django用户名的长度只能是30个字符,而sha1哈希是40个字符。奇怪的是,定制注册后端没有抱怨,可以存储sha1散列,但是表单在提交时会因为长度而产生错误

    \u init_uuu.py(我复制了现有的DefaultBackend并使用SHA1部分进行了修改)

    url.py

    url(r'^register/$', register, {'backend': 'registration.backends.default.RegBackend', 'form_class': UserRegistrationForm}, name='registration_register'),
    
    注册/视图.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)
    

    在视图中验证表单的位置创建用户名?我必须修改django注册视图,因为我没有编写该视图。但是我该如何设置用户名呢。我可以生成电子邮件的散列,但不确定我会如何处理散列。一种可能的方法是,不要对django注册做任何事情,只需隐藏模板上的用户名字段,当用户在提交之前提交表单调用javascript函数并生成用户名并在post中设置其值时,生成用户名的一个方法是在电子邮件的左侧部分进行更改。@Aamir,我想出了一个处理这个问题的好方法。看看我的答案。谢谢你的建议。
    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)