【问题标题】:Autogenerate a Django username with django-registration使用 django-registration 自动生成 Django 用户名
【发布时间】:2011-10-26 05:14:01
【问题描述】:

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

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

任何帮助都将不胜感激。

【问题讨论】:

  • 在您的视图中验证表单的位置创建用户名?
  • 我必须修改 django-registration 视图,因为我没有编写视图。我将如何设置用户名。我可以生成电子邮件的散列,但不确定我会如何处理散列。
  • 一种可能的方法是不对 django-registration 做任何事情,只需隐藏模板上的用户名字段,当用户提交表单时调用 javascript 函数,然后再提交并生成用户名并将其值设置为发布,生成用户名的一个想法是获取电子邮件的左侧部分并进行更改。
  • @Aamir,我想出了一个处理这个问题的好方法。看看我的回答。感谢您的建议。

标签: django django-registration


【解决方案1】:

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

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

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

【讨论】:

    【解决方案2】:

    我让它工作了。不得不直接修改注册的查看方式和默认注册后端,我感觉不太好。我希望在我自己的代码中进行这些更改,并且仍在努力进行这些更改,但这确实有效。

    我是这样做的:

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

    2. 将 urls.py 中的寄存器映射到我在步骤 1 中创建的新 RegBackend

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

    我没有对随机用户名使用 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)
    

    【讨论】:

      猜你喜欢
      • 2018-01-19
      • 2023-03-09
      • 1970-01-01
      • 1970-01-01
      • 2021-11-11
      • 2011-08-05
      • 1970-01-01
      • 2011-09-15
      • 2013-01-23
      相关资源
      最近更新 更多