Yes, there *is* a very simple way to implement “Email address as username”
-  you use a custom user model that implements that approach.

https://docs.djangoproject.com/en/1.8/topics/auth/customizing/#substituting-a-custom-user-model

Django’s docs contain details of how to do this, and there are a number of
third party projects that have a ready-to-use implementation of “email
address as username” specifically.

Yours,
Russ Magee %-)

On Wed, Nov 4, 2015 at 11:50 AM, Patrick Breitenbach <pbreitenb...@gmail.com
> wrote:

> Are you suggesting that there's a relatively easy way to implement "email
> address as username"? Is it as easy as just putting an email address into
> the username field? And making sure to update it when someone updates their
> email address?
>
>
> On Monday, January 19, 2015 at 2:33:35 AM UTC-8, James Schneider wrote:
>>
>> I guess I'm not clear on what you are trying to achieve. There are a
>> couple of scenarios to consider.
>>
>> As it stands with the default contrib.auth authentication backend,
>> sending both the username and email address entered by the user will only
>> work IF the user registered/was created using their email address as their
>> username, meaning that user.username is either their username (a string
>> that isn't their email), or an email address, regardless of what user.email
>> returns. The default contrib.auth authentication backend only looks at
>> user.username.
>>
>> What I suspect you want is to be able to use either user.username OR
>> user.email as the identifying tokens for the user in order to authenticate
>> them. For that, you'll need to roll at least a partial custom
>> authentication backend, in addition to the changes for the forms, etc. that
>> you've already laid out.
>>
>> From
>> https://docs.djangoproject.com/en/1.7/topics/auth/customizing/#writing-an-authentication-backend
>> :
>>
>> "If you wish to provide custom behavior for only part of the backend API,
>> you can take advantage of Python inheritance and subclass *ModelBackend*
>> instead of implementing the complete API in a custom backend."
>>
>> Specifically, you'll need to override the authenticate() method of the
>> authentication backend.
>>
>> I've done this, it's actually pretty easy. See:
>>
>>
>> https://github.com/django/django/blob/master/django/contrib/auth/backends.py#L11
>>
>> In this case, you should also roll a custom user model as well to ensure
>> that both user.username and user.email are unique columns. If you use the
>> email address as an identifying token, it will need to be unique among all
>> users, which is not true/enforced for the built-in contrib.auth User model.
>> You will also need to override the custom User manager for your new
>> CustomUser, probably with and override for get_by_natural_key(token) so
>> that the user can be retrieved in the backend authenticate() method. The
>> key change in get_by_natural_key() being the filter for the user object
>> being changed to something like User.objects.get(Q(username=token) |
>> Q(email=token)).
>>
>> (If you haven't seen the Q() notation, check
>> https://docs.djangoproject.com/en/1.7/ref/models/queries/#q-objects)
>>
>> The custom user you probably want is somewhat similar to the example
>> given in the docs:
>>
>>
>> https://docs.djangoproject.com/en/1.7/topics/auth/customizing/#a-full-example
>>
>> You'll need to add a 'username' field back in (remember to make it
>> unique) along with several other tweaks to be able to use either a username
>> or email field. An alternative would be a custom user class inheriting from
>> AbstractBaseUser and copying in the goodies you need from AbstractUser
>> (which is probably everything except the username and email fields, which
>> you'll be defining as unique). Be sure to include the Permission mixins
>> that AbstractUser has if you intend to use the built-in permission system
>> with your CustomUser.
>>
>> Sorry about the lengthy message, there are a bunch of ways to tackle
>> this, but ultimately I think you'll be rolling your own user and at least
>> part of the authentication system, not to mention having to customize the
>> user forms. The user will be slightly tricky, as there is no clear
>> inheritance path that will make it easy AFAICT, but the auth backend should
>> be just a class with a single authenticate() function if you inherit from
>> ModelBackend. Be sure to either include your custom backend in
>> AUTHENTICATION_BACKENDS, or possibly even replacing it if you go with the
>> Q() query I specified earlier (since an auth request using an email would
>> generate two authentication queries if both backends are used, and the
>> username field is checked twice).
>>
>> TL;DR; Overriding the user forms is probably not enough, you'll need a
>> custom user and custom authentication backend.
>>
>> Not sure if I made the situation better or worse, but HTH...
>>
>> Obviously, YMMV, I haven't tried this myself, but I have done a fair bit
>> of overriding for a custom object-based permission system, which touches
>> many of the same structures above.
>>
>> -James
>>
>>
>>
>>
>>
>>
>> On Mon, Jan 19, 2015 at 1:26 AM, Abraham Varricatt <
>> abraham....@googlemail.com> wrote:
>>
>>> Ignoring the malformed code, will the call to authenticate() even work
>>> without username? According to the docs,
>>>
>>> https://docs.djangoproject.com/en/1.7/topics/auth/default/#django.contrib.auth.authenticate
>>>
>>> It takes credentials in the form of keyword arguments, for the default
>>>> configuration this is username and password, and it returns a User
>>>> <https://docs.djangoproject.com/en/1.7/ref/contrib/auth/#django.contrib.auth.models.User>
>>>> object if the password is valid for the given username.
>>>>
>>>>
>>> If someone wanted to change the default behavior, I would expect them to
>>> at least override the function. OP doesn't seem to have done this, so it
>>> shouldn't even work. (Please correct me if I'm missing something)
>>>
>>> -Abraham V.
>>>
>>> On Friday, January 16, 2015 at 2:37:13 AM UTC+5:30, Matt Cooper wrote:
>>>>
>>>> Your if block in views.py is not well-formed. I haven't tested this but
>>>> I'd write it more like this:
>>>>
>>>>     # try username
>>>>     user = auth.authenticate(username=username, password=password)
>>>>     if user is not None:
>>>>         auth.login(request, user)
>>>>         return HttpResponseRedirect('/')
>>>>     # fall-through to email
>>>>     user = auth.authenticate(email=username, password=password)
>>>>     if user is not None:
>>>>         auth.login(request, user)
>>>>         return HttpResponseRedirect('/')
>>>>     # ok, neither one worked
>>>>     return HttpResponseRedirect('/accounts/invalid_login')
>>>>
>>>>
>>>> On Wednesday, January 14, 2015 at 10:07:29 PM UTC-8, Kakar Nyori wrote:
>>>>
>>>>> I have extendted the *UserCreationForm* with email and other fields,
>>>>> so that I could authenticate a user with both its username and email.
>>>>>
>>>>> forms.py:
>>>>>
>>>>>> class UserCreationForm(UserCreationForm):
>>>>>> class Meta:
>>>>>> model = User
>>>>>> fields = ('first_name', 'last_name', 'username', 'email',)
>>>>>
>>>>>
>>>>>
>>>>> views.py:
>>>>>
>>>>> def auth_view(request):
>>>>>>     username = request.POST.get('username','')
>>>>>>     password = request.POST.get('password','')
>>>>>>     user = auth.authenticate(username=username, password=password)
>>>>>>     if user is not None:
>>>>>>         auth.login(request, user)
>>>>>>         return HttpResponseRedirect('/')
>>>>>>     elif:
>>>>>>         user = auth.authenticate(email=username, password=password)
>>>>>>         if user is not None:
>>>>>>             auth.login(request, user)
>>>>>>             return HttpResponseRedirect('/')
>>>>>>     else:
>>>>>>         return HttpResponseRedirect('/accounts/invalid_login')
>>>>>
>>>>>
>>>>> html:
>>>>>
>>>>> <form action="/accounts/auth/" method="post">
>>>>>>     {%csrf_token%}
>>>>>>     <label for="name">Email or Username:</label>
>>>>>>     <input type="text" name="name" id="name" value="">
>>>>>>     <label for="password">Password:</label>
>>>>>>     <input type="password" name="password" id="password" value="">
>>>>>>     <input type="submit" value="LOGIN">
>>>>>> </form>
>>>>>
>>>>>
>>>>>
>>>>> In the views I tried giving both the *username* and *email *as input
>>>>> from the form as *name*, and check to see if username and password
>>>>> authenticate. If not then check whether email and password authenticate.
>>>>> But its not working. How do I solve this problem? Please kindly help me.
>>>>> Thank you.
>>>>>
>>>> --
>>> You received this message because you are subscribed to the Google
>>> Groups "Django users" group.
>>> To unsubscribe from this group and stop receiving emails from it, send
>>> an email to django-users...@googlegroups.com.
>>> To post to this group, send email to django...@googlegroups.com.
>>> Visit this group at http://groups.google.com/group/django-users.
>>> To view this discussion on the web visit
>>> https://groups.google.com/d/msgid/django-users/c7e27779-311b-43f4-b66d-d3548becdc26%40googlegroups.com
>>> <https://groups.google.com/d/msgid/django-users/c7e27779-311b-43f4-b66d-d3548becdc26%40googlegroups.com?utm_medium=email&utm_source=footer>
>>> .
>>>
>>> For more options, visit https://groups.google.com/d/optout.
>>>
>>
>> --
> You received this message because you are subscribed to the Google Groups
> "Django users" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to django-users+unsubscr...@googlegroups.com.
> To post to this group, send email to django-users@googlegroups.com.
> Visit this group at http://groups.google.com/group/django-users.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/django-users/e3b1bd4d-929d-4ea7-8220-512f12238a55%40googlegroups.com
> <https://groups.google.com/d/msgid/django-users/e3b1bd4d-929d-4ea7-8220-512f12238a55%40googlegroups.com?utm_medium=email&utm_source=footer>
> .
>
> For more options, visit https://groups.google.com/d/optout.
>

-- 
You received this message because you are subscribed to the Google Groups 
"Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-users+unsubscr...@googlegroups.com.
To post to this group, send email to django-users@googlegroups.com.
Visit this group at http://groups.google.com/group/django-users.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-users/CAJxq84_XjdD7jdf9mnOAt9wS19XDfeMA_gFxViWfpKmH6R%3DucA%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to