我正在尝试提供用户注册表单,而无需手动输入用户名。我设置了一个身份验证后端,以便用户可以使用电子邮件地址进行身份验证,这是有效的,因为我可以使用Django管理员用户登录。我的想法是我的应用程序将创建一个电子邮件地址的SHA1哈希值存储为Django用户名,用户永远不会看到这个。
我从注册html模板中删除了用户名字段,但我不确定应该以编程方式生成用户名的方式或位置。我认为它应该在RegistrationForm的clean_username方法中,但是当我使用没有username字段的模板时,不会调用该方法。
任何帮助肯定会受到赞赏。
答案 0 :(得分:1)
我得到了它的工作。我不得不直接修改注册的视图方法和默认注册后端。我希望在我自己的代码中进行这些更改,并且仍在努力进行这些更改,但这确实有效。
我是这样做的:
创建一个名为RegBackend的自定义注册后端,根据电子邮件地址生成sha1哈希,然后将hexdigest存储为用户名,最后返回User对象。
将urls.py中的地址注册到我在步骤1中创建的新RegBackend
修改了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)
答案 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。