How to extend default user model in django2.12 - python

I am working on a project and i am not using the default django user model instead i am using my own custom user model. but i am experiencing a problem. For my user model i have also made my own authb.py file which i have provided below and if i am using the default django authentication then it is authenticating only my superuser and not the user that i am entering through the sign up form and i am totally stuck.
first here is my authb.py
from .models import User
class AuthB:
def authenticate(self, username=None, password=None):
try:
user = User.objects.get(username=username)
return user
except:
return None
def get_user(self, user_id):
try:
return User.objects.get(pk=user_id)
except:
return None
but right now i am not using this authb instead i am using default authentication.
here is my models.py for user model
class User(models.Model):
is_authenticated = True
username = models.CharField(max_length= 25)
email = models.CharField(max_length= 150)
password = models.CharField(max_length= 100)
last_login = models.DateTimeField(auto_now= True)
profilepic = models.CharField(max_length= 255, default= "")
def __str__(self):
return self.username
here is my views.py file
def signup(request):
# context = {}
# return render(request, 'sign-up.html', context)
if request.method == 'POST':
# print(request.POST)
# Get form values
username = request.POST['username']
email = request.POST['email']
password = request.POST['password']
# Check if passwords match
# Check Username
if User.objects.filter(username=username).exists():
return redirect('signup')
else:
if User.objects.filter(email=email).exists():
return redirect('signup')
else:
u = User.objects.create_user(username=username, password=password, email=email)
u.save()
return redirect('login')
else:
return render(request, 'sign-up.html')
def login(request):
# context = {}
# return render(request, 'index.html', context)
if request.method =='POST':
# print(request.POST)
email = request.POST['email']
password = request.POST['password']
u= auth.authenticate(email=email, password=password)
return redirect('index')
else:
return render(request, 'login.html')
The main problem is that simple user is not able to login in my website only admin are able to login and django i not authenticating my simple user.

Related

django returning 'AnonymousUser' object has no attribute '_meta' error

I am developing a feature, when a user registers it automatically logs the user in
but i get 'AnonymousUser' object has no attribute '_meta' error.
but when i use the same code to login the user it works fine.
my forms.py:
from django.contrib.auth.forms import UserCreationForm
from django import forms
from django.core.exceptions import ObjectDoesNotExist
from django.contrib.auth.models import User
from .models import *
class RegisterForm(forms.Form):
fname = forms.CharField(error_messages=(), widget=forms.TextInput(attrs={"class":"fname entry", "placeholder":"First Name"}), required=True)
lname = forms.CharField(error_messages=(), widget=forms.TextInput(attrs={"class":"lname entry", "placeholder":"Last Name"}), required=True)
phone = forms.CharField(error_messages=(), widget=forms.TextInput(attrs={"class":"phone entry", "placeholder":"Phone Number"}), required=True)
password = forms.CharField(widget=forms.PasswordInput(attrs={"class":"password entry", "placeholder":"Password", "autocomplete":"off"}), required=True)
password2 = forms.CharField(widget=forms.PasswordInput(attrs={"class":"password entry", "placeholder":"Confirm Password", "autocomplete":"off"}), required=True)
def clean(self, *args, **kwargs):
fname = self.cleaned_data.get("fname")
lname = self.cleaned_data.get("lname")
phone = self.cleaned_data.get("phone")
password = self.cleaned_data.get("password")
password2 = self.cleaned_data.get("password2")
if phone and password and fname and lname and password2:
try:
user = User.objects.get(phone=PhoneNumber.objects.get(number=phone))
if user:
raise forms.ValidationError("user exists login instead")
except ObjectDoesNotExist:
pass
if password!=password2:
raise forms.ValidationError("passwords didn't match")
else:
if len(password)<8:
raise forms.ValidationError("short password! password should be longer than 8")
in my forms i have a registration form which does not inherit from django's user creation form.
my views.py:
def registerView(request):
if request.method == "POST":
form = RegisterForm(request.POST)
if form.is_valid():
fname = form.cleaned_data.get("fname")
lname = form.cleaned_data.get("lname")
username = generate_username(fname, lname)
phone = form.cleaned_data.get("phone")
u = User.objects.create_user(email="", first_name=fname, last_name=lname, username=username, is_active=False)
u.set_password(form.cleaned_data.get("password"))
u.save()
p = PhoneNumber(user=u, number=phone)
p.save()
phone = PhoneNumber.objects.get(number=phone)
u = User.objects.get(phone=phone)
userLogin = authenticate(username=username, password=u.password)
login(request, userLogin)
return redirect('home')
else:
form = RegisterForm()
return render(request, 'main/register.html', {'form':form})
my loginView:
def loginView(request):
if request.method == "POST":
form = LoginForm(request.POST)
if form.is_valid():
phone = PhoneNumber.objects.get(number=form.cleaned_data.get('phone'))
u = User.objects.get(phone=phone)
user = authenticate(username=u.username, password=form.cleaned_data.get('password'))
login(request, user, backend='django.contrib.auth.backends.ModelBackend')
print('success')
return redirect('home')
else:
form = LoginForm()
return render(request, 'main/login.html', {'form':form})
i have imported everything i need. the same code works with the loginView function but it doesn't work on registerView
What should i do to fix this?
You have this line in your view:
userLogin = authenticate(username=username, password=u.password)
The point to be noted here is that u is an instance of the user model and u.password will give the hashed password while authenticate expects it to be a raw password and hence returns None. In fact you don't even need to use authenticate while registering as you already have the user instance:
def registerView(request):
if request.method == "POST":
form = RegisterForm(request.POST)
if form.is_valid():
fname = form.cleaned_data.get("fname")
lname = form.cleaned_data.get("lname")
username = generate_username(fname, lname)
phone = form.cleaned_data.get("phone")
# removed `is_active=False` as per comment by #Nahu Gere
user = User.objects.create_user(email="", first_name=fname, last_name=lname, username=username) # better variable name
user.set_password(form.cleaned_data.get("password"))
user.save()
phone = PhoneNumber(user=user, number=phone)
phone.save()
login(request, user) # Directly use saved user instance
return redirect('home')
else:
form = RegisterForm()
return render(request, 'main/register.html', {'form':form})
I got this error because In my register view, I had this code:
user.is_active = False
user.save()
then I had so the user got logged in automatically after registering an account.
user = authenticate(username=user.username, password=raw_password)
login(request, user)
I solved it by commenting out the auto login
# user = authenticate(username=user.username, password=raw_password)
# login(request, user)

Understanding the def clean(self) method inside custom login form class

Django Version = 2.2.2.
Does it not make sense to take out the def clean(self) method from class LoginForm(form.ModelForm)
class LoginForm(forms.ModelForm):
password = forms.CharField(label='Password', widget=forms.PasswordInput)
class Meta:
model = Account
fields = ['email', 'password']
def clean(self):
if self.is_valid():
email = self.cleaned_data['email']
password = self.cleaned_data['password']
if not authenticate(email=email, password=password):
raise forms.ValidationError('Invalid login')
and put it inside the view function for login:
def login_screen_view(request):
context = {}
if request.POST:
form = LoginForm(request.POST)
if form.is_valid():
email = request.POST['email']
password = request.POST['password']
user = authenticate(email=email, password=password)
if user:
login(request, user)
return redirect('home')
else:
form = LoginForm()
context['login_form'] = form
return render(request, 'account/login.html', context)
So that the above two blocks of code becomes now this:
class LoginForm(forms.ModelForm):
password = forms.CharField(label='Password', widget=forms.PasswordInput)
class Meta:
model = Account
fields = ['email', 'password']
def login_screen_view(request):
context = {}
if request.POST:
form = LoginForm(request.POST)
if form.is_valid():
email = request.POST['email']
password = request.POST['password']
user = authenticate(email=email, password=password)
if user:
login(request, user)
return redirect('home')
else:
raise forms.ValidationError('Invalid login') #i added this line
else:
form = LoginForm()
context['login_form'] = form
return render(request, 'account/login.html', context)
The reason why I say all this is because in the def clean(self) method aren't you basically checking if the form is valid? We also check if the form is valid in the view as well. So why repeat the logic? Then if we cannot authenticate the user we raise a ValidationError which I think can be added in the view definition.

Django error: UNIQUE constraint failed: auth_user.username

I need to register a user by sending an activation token to her Email address. I am getting this error (UNIQUE constraint failed: auth_user.username) when trying to register her using custom built-in functions register and activate.
My code is as follows:
forms.py
class UserRegisterForm(forms.Form, UserCreationForm):
username = forms.CharField(max_length=20)
date_of_birth = forms.DateField(widget=forms.SelectDateWidget(years=range(2017, 1900, -1)))
email = forms.EmailField()
def clean_username(self):
username = self.cleaned_data.get('username')
if User.objects.filter(username__iexact=username).exists():
raise forms.ValidationError('Username already exists')
return username
def clean_date_of_birth(self):
'''
Only accept users aged 13 and above
'''
userAge = 13
dob = self.cleaned_data.get('date_of_birth')
today = date.today()
if (dob.year + userAge, dob.month, dob.day) > (today.year, today.month, today.day):
raise forms.ValidationError('Users must be aged {} years old and above.'.format(userAge))
return dob
def clean_email(self):
email = self.cleaned_data.get('email')
if User.objects.filter(email__iexact=email).exists():
raise forms.ValidationError('A user has already registered using this email')
return email
def clean_password2(self):
'''
we must ensure that both passwords are identical
'''
password1 = self.cleaned_data.get('password1')
password2 = self.cleaned_data.get('password2')
if password1 and password2 and password1 != password2:
raise forms.ValidationError('Passwords must match')
return password2
views.py
def register(request):
if request.method == 'POST':
form = UserRegisterForm(request.POST)
if form.is_valid():
username = form.cleaned_data.get('username')
email = form.cleaned_data.get('email')
password = form.cleaned_data.get('password1')
new_user = User.objects.create(username=username, email=email, password=password)
new_user = form.save(commit=False)
#new_user.set_password(password) # hashes the password
new_user.is_active = False
new_user.save()
current_site = get_current_site(request)
message = render_to_string('email_activation_link.html', {
'new_user':new_user,
'domain':current_site.domain,
'uid': urlsafe_base64_encode(force_bytes(new_user.pk)),
'token': account_activation_token.make_token(new_user),
})
mail_subject = 'Activate your Frac account.'
#to_email = form.cleaned_data.get('email')
email = form.cleaned_data.get('email')
to_email = EmailMessage(mail_subject, message, to=[email])#[to_email])
to_email.send()
return render(request, 'register_confirm.html', {'form': form})
else:
form = UserRegisterForm()
return render(request, 'register.html', {'form': form})
spec_backend = 'django.contrib.auth.backends.ModelBackend'
def activate(request, uidb64, token):
try:
uid = force_text(urlsafe_base64_decode(uidb64))
new_user = User.objects.get(pk=uid)
except(TypeError, ValueError, OverflowError, User.DoesNotExist):
new_user = None
if new_user is not None and account_activation_token.check_token(new_user, token):
new_user.is_active = True
new_user.save()
return render(request, 'register_complete.html', {})
else:
return render(request, 'registration_incomplete.html', {})
What is causing such an error? I researched similar posts on this platform but each case is unique.
You are getting the unique constraint error because you are trying to create the same user twice:
new_user = User.objects.create(username=username, email=email, password=password)
new_user = form.save(commit=False)
...
new_user.save()
Since you are using a model form, you don't need to call User.objects.create() manually. Remove that line. You can also remove the three lines above that fetch username, email and password from the cleaned data.
No need of such confusing type of answers , here's the simplest one that can be added to views.py, wherever you have handled your signup form.
It will just show the error without showing the default
(*Dont Copy this one)
UNIQUE constraint failed auth_user.username
Here's the code :-
(*Copy this one)
if User.objects.filter(username = username).first():
messages.error(request, "This username is already taken")
return redirect('home')

Why can't I create a custom user in Django using the UserCreationForm?

I am able to create a user from shell by importing the custom user model but when I apply the same method after submitting the form, the user is not created.
Below are the codes of my custom user model, UserCreationForm and view.
//model.py
class MyUser(AbstractBaseUser):
email = models.EmailField(
verbose_name='email address',
max_length=255,
unique = True,
)
is_active = models.BooleanField(default=True)
is_admin = models.BooleanField(default=False)
objects = MyUserManager()
USERNAME_FIELD = 'email'
def get_full_name(self):
# The user is identified by their email address
return self.email
def get_short_name(self):
# The user is identified by their email address
return self.email
def __str__(self): # __unicode__ on Python 2
return self.email
def has_perm(self, perm, obj=None):
"Does the user have a specific permission?"
# Simplest possible answer: Yes, always
return True
def has_module_perms(self, app_label):
"Does the user have permissions to view the app `app_label`?"
# Simplest possible answer: Yes, always
return True
#property
def is_staff(self):
"Is the user a member of staff?"
# Simplest possible answer: All admins are staff
return self.is_admin
I have extended the AbstractBaseUser as suggested in the Django docs to create a custom user model.
//forms.py
class UserCreationForm(forms.ModelForm):
"""A form for creating new users. Includes all the required
fields, plus a repeated password."""
email = forms.EmailField(
label='Email',
widget=forms.EmailInput,
required=True,
)
password1 = forms.CharField(
label='Password',
widget=forms.PasswordInput,
required=True
)
password2 = forms.CharField(
label='Password confirmation',
widget=forms.PasswordInput,
required=True
)
class Meta:
model = MyUser
fields = ('email', 'password1', 'password2')
def clean_password2(self):
# Check that the two password entries match
password1 = self.cleaned_data.get("password1")
password2 = self.cleaned_data.get("password2")
if password1 and password2 and password1 != password2:
raise forms.ValidationError("Passwords don't match")
return password2
def save(self, commit=True):
# Save the provided password in hashed format
user = super(UserCreationForm, self).save(commit=False)
user.set_password(self.cleaned_data["password1"])
if commit:
user.save()
return user
Am I doing incorrect form processing. The form.save() method didn't work out for me. Also the docs don't discuss user registration thoroughly. I don't know why.
//views.py
def login(request):
if request.method == 'POST':
form = AuthenticationForm(data=request.POST)
if form.is_valid():
user = authenticate(email=request.POST['email'],
password=request.POST['password'])
if user is not None:
if user.is_active:
django_login(request, user)
return redirect('/home/', permanent=True)
else:
form = AuthenticationForm()
return render(request, 'buymeauth/login.html', {'form': form})
def register(request):
user = request.user
if request.method == 'POST':
form = UserCreationForm(data=request.POST)
if form.is_valid():
my_user = MyUser(user.email, user.password)
my_user.save()
return redirect('/home/', permanent=True)
else:
form = UserCreationForm()
return render(request, 'buymeauth/register.html', {'form': form})
I am new to Django but not particularly to web development. I have some exposure with MEAN but I am finding Django difficult. I have been stuck with this authentication and authorisation stuff for 5 days now.
def register(request):
# this is the logged-in user
user = request.user
if request.method == 'POST':
# this is the form with the submitted data
form = UserCreationForm(data=request.POST)
if form.is_valid():
# the submitted data is correct
my_user = MyUser(user.email, user.password)
# this is a new user with the same email and password
# than the currently logged-in user. It's not what you want
# and it won't work if you're not logged-in
my_user.save()
return redirect('/home/', permanent=True)
else:
form = UserCreationForm()
return render(request, 'buymeauth/register.html', {'form': form})
Instead you probably want this:
if request.method == 'POST':
form = UserCreationForm(data=request.POST)
if form.is_valid():
user = form.save(commit=False)
user.is_active = True # if you want to skip email validation
user.email = User.objects.normalize_email(user.email)
user.save()

Show profile of custom user in django

hi i a working on a project for that i have made login and registration of a user. now i want to show full profile of user.since get_profile is not working anymore so how can i get full profile of a user
my models.py
class Consultants(models.Model):
consul_id=models.IntegerField(default=0,primary_key=True)
first_name=models.CharField(max_length=255,blank=True,null=True)
last_name=models.CharField(max_length=255,blank=True,null=True)
email=models.EmailField(max_length=255,blank=True,null=True)
username=models.CharField(max_length=255,blank=True,null=True)
password=models.CharField(max_length=50,blank=True,null=True)
last_login=models.DateTimeField(default=datetime.now,blank=True,null=True)
is_active=models.BooleanField(default=False)
def __str__(self):
return self.first_name
views.py for login and registration
def register(request):
context = RequestContext(request)
registered = False
if request.method == 'POST':
# user_form = UserForm(data=request.POST)
consultant_form = ConsultantsForm(data=request.POST)
if consultant_form.is_valid():
consultant = consultant_form.save(commit=False)
consultant.save()
registered = True
else:
print consultant_form.errors
else:
consultant_form = ConsultantsForm()
return render_to_response(
'register.html',
{'consultant_form': consultant_form, 'registered': registered},
context_instance=RequestContext(request))
def login_user(request):
context = RequestContext(request)
if request.method == 'POST':
username = request.POST['username']
password = request.POST['password']
print type(username)
print "username",username
try:
user = Consultants.objects.get(Q(username= username) & Q(password= password))
print 'chala'
if user.is_active:
user.backend = 'django.contrib.auth.backends.ModelBackend'
login(request, user)
return HttpResponse("welcome......you are succesfuly log in")
else:
return HttpResponse("Your UkKonnect account is disabled.")
except ObjectDoesNotExist:
return HttpResponse("INvalid User")
else:
return render_to_response('login.html', {}, context)
i want to make def full_profile and def edit_profile.
How can i get logged in user consul_id??
please help me
Not sure that I understand you problem well.. Take a look at recommended way of extending User model:
https://docs.djangoproject.com/en/dev/topics/auth/customizing/#extending-the-existing-user-model
from django.contrib.auth.models import User
class Employee(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
department = models.CharField(max_length=100)
Then you can do:
u = User.objects.get(username='fsmith')
freds_department = u.employee.department
In your case it would be:
class Consultant(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
*your fields here*
Now you can use standard authentication forms and methods
You always can obtain consultant data as:
request.user.consultant

Categories

Resources