On 20/11/2017 6:40 PM, Mike Dewhirst wrote:
> I have seen the two tickets and read the developer list thread[1]on
> this subject. Is there a best-practice approach to preventing
> usernames which are case-insensitively equivalent
>
> I'm hoping someone has achieved this and might be willing to share.
This is working so I would appreciate any constructive criticism leading
to a better approach.
Thanks
Mike
# common.models
from django.contrib.auth.models import AbstractUser, UserManager
from django.utils.encoding import python_2_unicode_compatible
class InsensitiveUserManager(UserManager):
def get_by_natural_key(self, username):
return self.get(**{'username__iexact': username})
@python_2_unicode_compatible
class User(AbstractUser):
objects = InsensitiveUserManager()
def __str__(self):
return u'%s' % self.username
def save(self, *args, **kwargs):
super(User, self).save(*args, **kwargs)
# not sure whether to use the post-save signal or just save it here
profile = UserProfile.objects.get_or_create(user=self)[0]
profile.save()
# common.forms
from django.contrib.auth.forms import UserCreationForm
from .models import User
class CommonUserCreationForm(UserCreationForm):
"""
https://docs.djangoproject.com/en/1.11/topics/auth/customizing/#
custom-users-and-the-built-in-auth-forms
"""
first_name = forms.CharField(
max_length=30,
required=False,
help_text='Optional',
)
last_name = forms.CharField(
max_length=30,
required=False,
help_text='Optional'
)
email = forms.EmailField(
max_length=254,
help_text='Required'
)
class Meta(UserCreationForm.Meta):
model = User
fields = UserCreationForm.Meta.fields
# common.views
from django.contrib.auth import authenticate, get_user_model, login
from django.contrib.auth.decorators import login_required
from django.shortcuts import redirect, render
from .exceptions import ValidationError
from .forms import CommonUserCreationForm
def register_user(request):
if request.method == 'POST':
form = CommonUserCreationForm(request.POST)
username = form.data.get('username')
try:
User = get_user_model()
i_username = User.objects.get(username__iexact=username).username
if i_username.lower() == username.lower():
form.add_error(
'username',
ValidationError('{} already exists'.format(i_username))
)
except User.DoesNotExist:
pass # bonus!
if form.is_valid():
username = form.cleaned_data.get('username')
form.save()
raw_password = form.cleaned_data.get('password1')
user = authenticate(username=username, password=raw_password)
login(user)
return redirect('common.views.homepage')
else:
form = CommonUserCreationForm()
return render(request, 'register.html', {'form': form})
# templates/register.html
{% extends 'base_site.html' %}
{% block content %}
<h2>Register</h2>
<form method="post">
{% csrf_token %}
{% if form.errors %}
{{ form.errors }}
{% endif %}
<table>
{% for field in form %}
<tr>
<td width='154px'>{{ field.label }}:</td>
<td width='170px'>{{ field }}</td>
<td>{{ field.help_text | safe }}</td>
</tr>
{% endfor %}
</table>
<button type="submit">Register</button>
</form>
{% endblock %}