How to have django auth take username and firstname same value? - python

Django auth has username and first_name fields. But username has field option unique=True. This prevents a user from giving first_name same as username when registering and raises IntegrityError. How to bypass this and also keeping username unique? ie. no two users should have the same username. But username can be same as first_name. And two users can have same first_name, last_name.

You cannot achieve that. If you want to have the same value in fields first_name and username and one of them is not unique, the other one also cannot be unique.
As far as I understand what you're doing here, you just want to display first_name instead of username - to achieve that just use {{ user.first_name }} instead of just {{ user }}. If you need to store some additional information about users you can also define Profiles where you can implement your own __str__ method.

You will have to implement custom authentication backend that used first_name as username.
During registration, you can duplicate username with first_name or generate random username which you will never use, as you will always use first_name instead.
You will have have to take care of
Take create while creating/registering user.
Username (in your case first name) should be unique
The code in authentication backend would be something like (this is just a sample code):
def authenticate(self, username=None, password=None):
try:
user = User.objects.get(first_name=username)
if user.check_password(password):
return user
except User.DoesNotExist:
return None
Refer Writing authentication backend.
There are quite a few examples of how to user email to authenticate that you can refer to authenticate using first_name.

Related

How to change the field name of Serialzed User Model on frontend in Django Rest Framework?

I am making a simple Login/Logout App using REST API in Django DRF. I am using the default User model for this behavior.
In the Login API, I wanted to authenticate the user with email, hence I wrote the custom authentication using ModelBackend. Everything works fine.
But, I want to change the word username to email in the front of the Login API. I tried using the source attribute, but it does not change. Is there any easy way to do it? I am looking for something like verbose_name, that is used in Django Models.
My serializers.py is:
class LoginSerializer(serializers.Serializer):
username = serializers.CharField(source='Email')
password = serializers.CharField()
def validate(self, data):
user = authenticate(**data)
if user and user.is_active:
return user
raise serializers.ValidationError('Incorrect Credentials Passed.')
Again, I am using the default User Model, and I don't want to overwrite/override/extend the User Model. I just want to change the name of the field username on the frontend to be shown as email.
You need to pass a value called email and not username to your ModelBackend subclass:
class LoginSerializer(serializers.Serializer):
username = serializers.CharField()
password = serializers.CharField()
def validate(self, data):
user = authenticate(**{'email': data['username'], 'password': data['password']})
if user and user.is_active:
return user
raise serializers.ValidationError('Incorrect Credentials Passed.')

Django Python change user default attributes for authentication

In Django, the default attributes for user:
username
password
email
first_name
last_name
I would like to remove email, first_name, last_name
and replace it with company
Is that possible ? Can someone show me the process of performing an authentication session with these 3 modified attributes:
- company
- username
- password
Thanks.
You should read the documentation regarding customizing authentication in Django especially the part regarding User model substitution if you would like to create your own model.

Storing password in multiple entities - Django

I'm working on Django project and I want to have two different entities in database - (default Django) User and Doctors. I want to have stored password in both entities.
def post(self, request, pk):
username = Doctor.objects.get(pk=a).email
password = Doctor.objects.get(pk=a).password
user = User.objects.create_user(username, username, password)
user.save()
return redirect('ps:index')
Atribute in forms.py for DoctorForm:
password = forms.CharField(widget=forms.PasswordInput)
But this is not working for passwords. I assume that the reason is hashing and salt. How to solve it?
Any help would be appreciated.
The password stored in database is hashed. If you want to save a new password, use user.set_password(new_password) and user.save(). Then copy the user.password to another entity.

Django form subclass non-functional

Here is a custom registration form inheriting from [django-registration][1]. My extra form fields do not appear and field cleaning methods do not run, something which I observe from the functionality and supported by the print statements (the Custom form runs print statement runs but not 'Custom Password clean'. Both the field appears and the validations run when placed into the original django-registration code, provided below.
Why is this happening?
my app/forms.py
from registration.forms import RegistrationForm
class CustomRegistrationForm(RegistrationForm):
"""
Form for registering a new user account.
Validates that the requested username is not already in use, and
requires the password to be entered twice to catch typos.
I have has added email uniqueness validation and minimum
password length validation.
Subclasses should feel free to add any additional validation they
need, but should avoid defining a ``save()`` method -- the actual
saving of collected user data is delegated to the active
registration backend.
"""
print 'Custom form runs'
LOCALITIES = (
('1', 'London'),
('2', 'Berlin'),
)
locality = forms.MultipleChoiceField(choices=LOCALITIES,
label='Where are you?',
widget=forms.CheckboxSelectMultiple)
def clean_password1(self):
"""
Verify that password is longer than 5 characters.
"""
print 'Custom Password clean'
password = self.cleaned_data['password1']
print 'custom valid'
if len(password) < 6:
raise forms.ValidationError(_("Password needs to be at least 6 characters long"))
return password
def clean_email(self):
"""
Validate that the supplied email address is unique for the site.
"""
email = self.cleaned_data['email']
if User.objects.filter(email__iexact=self.cleaned_data['email']):
raise forms.ValidationError(_("This email address is already in use. \
Please supply a different email address."))
return email
django-registration
registration/forms.py
"""
Forms and validation code for user registration.
Note that all of these forms assume Django's bundle default ``User``
model; since it's not possible for a form to anticipate in advance the
needs of custom user models, you will need to write your own forms if
you're using a custom model.
"""
from django.contrib.auth.models import User
from django import forms
from django.utils.translation import ugettext_lazy as _
class RegistrationForm(forms.Form):
"""
Form for registering a new user account.
Validates that the requested username is not already in use, and
requires the password to be entered twice to catch typos.
Subclasses should feel free to add any additional validation they
need, but should avoid defining a ``save()`` method -- the actual
saving of collected user data is delegated to the active
registration backend.
"""
required_css_class = 'required'
username = forms.RegexField(regex=r'^[\w.#+-]+$',
max_length=30,
label=_("Username"),
error_messages={'invalid': _("This value may contain only letters, numbers and #/./+/-/_ characters.")})
email = forms.EmailField(label=_("E-mail"))
password1 = forms.CharField(widget=forms.PasswordInput,
label=_("Password"))
password2 = forms.CharField(widget=forms.PasswordInput,
label=_("Password (again)"))
def clean_username(self):
"""
Validate that the username is alphanumeric and is not already
in use.
"""
existing = User.objects.filter(username__iexact=self.cleaned_data['username'])
if existing.exists():
raise forms.ValidationError(_("A user with that username already exists."))
else:
return self.cleaned_data['username']
def clean_email(self):
"""
Validate that the supplied email address is unique for the site.
"""
email = self.cleaned_data['email']
if User.objects.filter(email__iexact=self.cleaned_data['email']):
raise forms.ValidationError(_("This email address is already in use. \
Please supply a different email address."))
return email
def clean(self):
"""
Verify that the values entered into the two password fields
match. Note that an error here will end up in
``non_field_errors()`` because it doesn't apply to a single
field.
"""
if 'password1' in self.cleaned_data and 'password2' in self.cleaned_data:
if self.cleaned_data['password1'] != self.cleaned_data['password2']:
raise forms.ValidationError(_("The two password fields didn't match."))
return self.cleaned_data
That's not how you customise a class based view. The third parameter in a urlconf is for parameters that are passed as part of the request, alongside those captured from the URL itself: it's not for configuring the class view.
To do that, you should either override the class in your code and set the attributes there, or you can pass them as parameters to the class's as_view() method:
url(r'^register/$', RegistrationView.as_view(form_class=CustomRegistrationForm, backend=registration.backends.default.DefaultBackend), name='registration_register'),

Django override default functionalities

In django/django/contrib/auth/forms.py how to override the default method
and include the same in the users module ?
So my intention is that i want to change the username field length to 64 characters but this would not be correct to do this in django directories,because whenever new version is downloaded this file has to changed....
What exactly shoudl be changed to do this
class AuthenticationForm(forms.Form):
"""
Base class for authenticating users. Extend this to get a form that accepts
username/password logins.
"""
username = forms.CharField(label=_("Username"), max_length=30)
password = forms.CharField(label=_("Password"), widget=forms.PasswordInput)
#Deniz Dogan: You also have to convince login view to use the custom form:
login(request, authentication_form=MyAuthenticationForm)
If I understand you correctly, you may be able to change it by sub-classing AuthenticationForm into e.g. MyAuthenticationForm:
class MyAuthenticationForm(AuthenticationForm):
username = forms.CharField(label=_("Username"), max_length=64)
This way, you would keep the validators from AuthenticationForm, but still let the username be 64 characters long.

Categories