Django custom Authentication get_user() error - django

The views.py
def login_form_student(request):
if request.method =='POST':
roll_no = request.POST.get('username')
password = request.POST.get('pass')
user = authenticate(request, uniq_id=roll_no,password=password)
if user is not None:
login(request,user)
return redirect('/userdetails/prof_page/')
else:
return redirect('/userdetails/thankyoupage/')
return render(request,'user_interaction/login_form.html')
The custom backend
from .models import user_detail
from django.contrib.auth.backends import ModelBackend
class user_auth_custom(ModelBackend):
def authenticate(self,request,uniq_id,password):
flag = 0
try:
user = user_detail.objects.get(roll_no=uniq_id)
if password == user.password:
flag = 1
return user
except flag == 0:
pass
return None
def get_user(self,user_id):
try:
return user_detail.objects.get(pk=user_id)
except user_detail.DoesNotExist:
return None
The models.py
class user_detail(models.Model):
full_name = models.CharField(max_length=264,null=True)
roll_no = models.CharField(max_length=264,unique=True,primary_key=True)
management_name = models.CharField(max_length=264)
contact_no = models.CharField(max_length=10)
email = models.EmailField(max_length=254)
department = models.CharField(max_length=264)
residential_status = models.CharField(max_length=264)
password = models.CharField(max_length=32,default='fmspsg2020')
last_login = models.DateTimeField(auto_now=True)
I get a Validation Error.
['“18pw13” value must be an integer.']
18pw13 is actually a roll_no.
What should i do?
Should i create a new user_id attribute to the model of IntegerField?

Why don't you just inherit the user model from djangos AbstactBaseUser, it makes it alot easier, because you get all the user functionallity that the Django user provides.
Here is a link:
https://docs.djangoproject.com/en/3.0/topics/auth/customizing/#specifying-a-custom-user-model

Related

Can't get Django forms to save to User and Profile model

I am trying to extend the Django User model by creating a user Profile model. When users register for the site, I want them to be able to select what class period they are in. To do this, I've tried to create a form that alters the User model, and a form that alters the Profile model. The problem is that when I try to put both forms into 'users/register.html' I am getting an error that says 'Anonymous User has to data _meta'. Below is my original code that only has the form for altering the User model in 'users/register.html'. How can I configure the registration so that users are able to save to the User and Profile model when they are first signing up for the site?
models.py
class Profile(models.Model):
'''
periods = [
('-','-'),
('1','1'),
('2','2'),
('3','3'),
('4','4'),
('6','6'),
('7','7'),
]
'''
user = models.OneToOneField(User,on_delete=models.CASCADE)
period = models.IntegerField(default=1)
first_name = models.CharField(max_length=100,default='Home')
last_name = models.CharField(max_length=100,default='Simpson')
def __str__(self):
return f'{self.user.username}'
forms.py
class UserRegisterForm(UserCreationForm):
email = forms.EmailField()
class Meta:
model = User
fields = ['username','email','password1','password2']
class UserProfileForm(forms.ModelForm):
periods = [
(1,1),
(2,2),
(3,3),
(4,4),
(6,6),
(7,7),
]
period = forms.ChoiceField(choices=periods)
first_name = forms.CharField(max_length=100)
last_name = forms.CharField(max_length=100)
class Meta:
model = Profile
fields = ['first_name','last_name','period']
signals.py
#receiver(post_save,sender=User)
def create_profile(sender,instance,created,**kwargs):
if created:
Profile.objects.create(user=instance)
#receiver(post_save,sender=User)
def save_profile(sender,instance,**kwargs):
instance.profile.save()
views.py
def login(request):
context = {
'title':'Login',
}
return render(request,'users/login.html',context)
def register(request):
if request.method == "POST":
form = UserRegisterForm(request.POST)
if form.is_valid():
email = form.cleaned_data.get('email')
email_domain = re.search("#[\w.]+", email)
if email_domain.group() == EMAIL_DOMAIN:
form.save()
username = form.cleaned_data.get('username')
messages.success(request,f'Account created for {username}! You are now able to sign in.')
return redirect('users-login')
else:
messages.error(request,f'Sorry. You are not authorized to register.')
else:
form = UserRegisterForm()
context = {
'title':'Register',
'form':form
}
return render(request,'users/register.html',context)
This is happening because you are putting both the forms in the register page . When you have not created any user so how you can create a profile and how would you be able to add or retrieve data from it?
Now the solution for that is ,
1 . You create a page for registering the user say "users/register.html" , when they successfully register there, create a signal for creating the Profile for him , then successfully log the user in . Then redirect the just registered user to the profile change page.
Take both the forms in the user register page but do not validate the profile_change form .Create the user in the view and then reference it to the profile_change_form .
A simple code bit for that .
def registerUser(request) :
if request.method == "POST" :
user_form = UserRegisterForm(request.POST)
if user_form.is_valid():
username = request.POST.get("username")
# fields you require
user = User(username = username , password = password)
user.save()
profile_field_objects = request.POST.get("profile_field_data")
profile = Profile(user = user , profile_field_objects = profile_field_objects)
profile.save()
# rest you can code

I am unable to login as an organization in django views

I have requirement to build a crm . In that i have 3 things 1 is super user who is there by default.
Second organization in which I use a foreign key of user because I don't want to create a custom user and re write a lot of things third agent who is user as foreign key and connected to an organization no I want to login as organization in the dashboard if I am using the super user as login credential it is telling me required organization instance if I am login using organization account it is giving error NoReverseMatch at /leads/login_handle
Here is my views.py
login and sign up handle code
def signup_handle(request):
if request.method == "POST":
name = request.POST.get('name')
email = request.POST.get('email')
pass1 = request.POST.get('pass')
pass2 = request.POST.get('re_pass')
pass2 = request.POST.get('re_pass')
check = request.POST.get('agree-term')
if(pass1 != pass2):
return HttpResponse("Babe your passwod does not matches please try again")
else:
x = User.objects.create(email = email,username = email,first_name = name,is_staff = False)
# x = User.objects.create(name,email,pass1)
x.set_password(pass1)
x.save()
y = Organization(user = x,name = name)
y.save()
# print(f"lets verify the data name = {name},{check}")
return HttpResponse("Babe you have successfully created your account")
else:
return HttpResponse("Babe something goes wrong")
def login_handle(request):
if request.method == "POST":
username = request.POST.get('your_name')
password = request.POST.get('your_pass')
# username = email
# print(f"{username} and password is {password}")
user = authenticate(request,username=username,password=password)
if user is not None:
login(request, user)
return redirect('')
else:
return HttpResponse("Babe try again you are not authenticated")
else:
return HttpResponse("babe only post method applicable")
here is my complete models.py file
from ckeditor.fields import RichTextField
from django.db import models
from django.contrib.auth.models import User
from ckeditor.fields import RichTextField
# Create your models here.
class Source(models.Model):
name = models.CharField(max_length=50,blank=True)
def __str__(self):
return self.name
class Followup(models.Model):
created_by = models.CharField(max_length=20,blank=True,null=True)
body = RichTextField(blank = True,null = True)
created_date = models.DateTimeField(auto_now_add=True)
updated_date = models.DateTimeField(auto_now_add=True)
class Organization(models.Model):
name = models.CharField(max_length=50,blank=True)
user = models.ForeignKey(User,on_delete=models.PROTECT,blank=True)
def __str__(self):
return self.name
class Agent(models.Model):
name = models.CharField(max_length=20,blank=True)
user = models.ForeignKey(User,on_delete=models.PROTECT,blank=True)
image = models.ImageField(upload_to="Agents/images",blank = True)
organization = models.ForeignKey(Organization,on_delete=models.PROTECT,blank=True,default="")
def __str__(self):
return self.name
class Lead(models.Model):
status = (
("fresh","Fresh"),
("open","Open"),
("closed","Closed"),
("pending","Pending"),
)
closed_by = (
("low_budget","Low Budget"),
("we_cant_do","We Cant Do"),
("client","Client Converted"),
)
pending_by = (
("with_customer","With Customer"),
("with_process","With Process"),
("pending_on_us","Pending On Us"),
)
name = models.CharField(max_length=20,blank=True)
email = models.CharField(max_length=30,default="")
assign_to = models.CharField(max_length=30,default="")
mobile_no = models.IntegerField(blank=True)
subject = models.CharField(max_length=100,blank=True)
message = models.TextField(blank=True)
source = models.CharField(max_length=30,default="")
# source = models.ForeignKey(Source,blank=True,on_delete=models.PROTECT,null=True)
created_date = models.DateTimeField(auto_now_add=True)
updated_date = models.DateTimeField(auto_now_add=True)
state = models.CharField(choices=status,max_length=20,blank=True,default="fresh")
closed_by = models.CharField(max_length=15,choices=closed_by,blank=True)
pending_by = models.CharField(max_length=15,choices=pending_by,blank=True)
image=models.ImageField(upload_to="lead/images",blank = True)
def __str__(self):
return self.name
As the first answer says i added a path in redirect now it logged in but not rendering the page
def login_handle(request):
if request.method == "POST":
username = request.POST.get('your_name')
password = request.POST.get('your_pass')
# username = email
# print(f"{username} and pasword is {password}")
user = authenticate(request,username=username,password=password)
if user is not None:
login(request, user)
return redirect('/')
else:
return HttpResponse("Babe try again you are not authenticated")
else:
return HttpResponse("babe only post method applicable")
I am getting the error
Here is my app name home urls.py
urls.py
from django.contrib import admin
from django.urls import path
from home import views
urlpatterns = [
path('',views.index,name="index"),
# create agent
path('create_agent_page',views.create_agent_page,name="create_agent_page"),
path('create_agent',views.create_agent,name="create_agent"),
path('signup_page',views.signup_page,name="signup_page"),
path('login_page',views.login_page,name="login_page"),
path('signup_handle',views.signup_handle,name="signup_handle"),
path('login_handle',views.login_handle,name="login_handle"),
#Lead handleing
path('create_lead',views.create_lead_page,name="create_lead"),
path('follow_up/<int:id>',views.follow_up,name="follow_up"),
path('update_lead/<int:id>',views.update_lead,name="update_lead"),
# path('update_lead',views.update_lead,name="update_lead"),
path('creat_handle_lead',views.creat_handle_lead,name="creat_handle_lead"),
path('lead_list',views.lead_list,name="lead_list"),
]
here is my project urls.py
from django.contrib import admin
from django.urls import path
from django.urls.conf import include
urlpatterns = [
path('admin/', admin.site.urls),
path('leads/', include('home.urls')),
]
return redirect('')
This is wrong. You must do
from django.urls import reverse
return HttpResponseRedirect(reverse('app_name:url_pattern_name'))
or you can specify your url pattern manually
from django.urls import reverse
return HttpResponseRedirect('/dashboard/')

How to associate data sent by a user to his own account in Django

I have a model called KeyFormModel which has 2 fields "secret_key" and "primary_key", I pointed this model towards a form and called this form to a view and template. each user has exactly one primary_key and one secret_key, when I send this to model they are mixing with other keysets
this is my model
class KeyFormModel(models.Model):
username = models.ForeignKey(settings.AUTH_USER_MODEL,on_delete=models.CASCADE)
primary_key = models.CharField(max_length=200)
secret_key = models.CharField(max_length=200)
def __str__(self):
return username+"_keys"
class Meta:
verbose_name_plural = 'Keys'
this is my form
from ..models import KeyFormModel
from django import forms
from django.conf import settings
class KeyForm(forms.ModelForm):
primary_key = forms.CharField(required=True)
secret_key = forms.CharField(required=True,widget = forms.PasswordInput)
class Meta:
model = KeyFormModel
fields = ("username","primary_key","secret_key")
this is my view
#cache_control(no_cache=True, must_revalidate=True)
#login_required(login_url='../login')
def AccountView(request):
if(request.method == 'POST'):
form =KeyForm(request.POST)
if(form.is_valid()):
form.save()
else:
for msg in form.error_messages:
messages.error(request,f"{msg}")
form = KeyForm
return(render(request, 'accountView.html',context={"form":form}))
as you can see I am trying to add username from AUTH_USER_MODEL after logging into that account but failing miserably. please hlp
What worked out for me:
import User to models:
from django.contrib.auth.models import User
and in the specific model add user field:
user = models.ForeignKey(
User,
on_delete=models.CASCADE,
)
i found the answer
#cache_control(no_cache=True, must_revalidate=True)
#login_required(login_url='../login')
def AccountView(request):
keyforce=KeyFormModel.objects.filter(user=request.user)
if(keyforce):
return(render(request,'keyView.html',{"keys":keyforce}))
else:
if(request.method == 'POST'):
form = KeyForm(request.POST)
if(form.is_valid()):
primary_key = request.POST['primary_key']
secret_key = request.POST['secret_key']
new = KeyFormModel(primary_key=primary_key,
secret_key=secret_key, user=request.user)
new.save()
return(redirect("main:Account"))
else:
for msg in form.error_messages:
messages.error(request, f'{msg}')
else:
form = KeyForm
return(render(request, 'accountView.html', context={"form": form}))
I learned that the values to the models can be added through views itself,
all I did was something like this
after adding User to your model
in view create
form = yourModel(user = request.user)
voila its done

Django: Check instance if it exists in User Database and save to App Model Database

I this in my forms.py
from django.contrib.auth.models import User
from .models import DirectReferral, IndirectReferral
class RegistrationForm(forms.Form):
username = forms.RegexField()
referrer = forms.CharField()
def clean_username(self):
try:
user = User.objects.get(username__iexact=self.cleaned_data['username'])
except User.DoesNotExist:
return self.cleaned_data['username']
raise forms.ValidationError(_("The username already exists."))
How do I check if the referrer instance exist in User Database?
I did the code below but it has an error of TypeError at /register/
def clean_referrer(self):
try:
user = User.objects.get(username__iexact=self.cleaned_data['referrer'])
except User.DoesNotExist:
raise forms.ValidationError(_("User does not exist."))
return self.cleaned_data['referrer']
I did also try to do this but I get an error of string indices must be integers.
def clean(self):
if 'referrer' in self.cleaned_data:
if User.objects.filter(username=self.cleaned_data['referrer']).exists():
return self.cleaned_data['referrer']
else:
raise forms.ValidationError(_("Referrer doesn't exist!"))
Here is my models.py
from django.contrib.auth.models import User
class DirectReferral(models.Model):
name = models.OneToOneField(User, primary_key=True)
referrer = models.ForeignKey(User, related_name="direct_referrals")
def __str__(self):
return self.name.username
class IndirectReferral(models.Model):
name = models.OneToOneField(User, primary_key=True)
referrer = models.ForeignKey(User, related_name="indirect_referrals")
def __str__(self):
return self.name.username
How do I get the referrer instance data?
Here is my views.py (Updated)
def register(request):
if request.method == 'POST':
form = RegistrationForm(request.POST)
if form.is_valid():
user = User.objects.create_user(
username=form.cleaned_data['username']
)
ref_user = User.objects.get(
username=form.cleaned_data['referrer'])
direct = DirectReferral.objects.create(
name = user,
referrer = ref_user
)
if DirectReferral.objects.filter(referrer=user).exists():
indirect = IndirectReferral.objects.create(
name = user,
referrer = ref_user
)
return HttpResponseRedirect('/register/success/')
This is what you need:
def register(request):
if request.method == 'POST':
form = RegistrationForm(request.POST)
if form.is_valid():
user = User.objects.create_user(
username=form.cleaned_data['username'],
)
# Assuming form.cleaned_data['referrer'] has usernames.
# If it has pks then just use pk=form.cleaned_data['referrer']
# You should wrap this in a try-except
dr_user = User.objects.get(username=form.cleaned_data['referrer'])
direct_referral = DirectReferral.objects.create(
user=user,
referrer=dr_user,
)
# Wrap this in try-except as well.
ir_user = dr_user.direct_referral.referrer
indirect_referral = IndirectReferral.objects.create(
user=user,
referrer=ir_user,
)
return HttpResponseRedirect('/register/success/')
Also, this looks like a job for post_save signals. Check them out here: https://docs.djangoproject.com/es/1.9/ref/signals/#post-save
I think the problem is here
DirectReferral.name = username,
DirectReferral.referrer = referrer,
IndirectReferral.name = username,
IndirectReferral.referrer = referrer,
you have to create objects first and than assign the values like this:
direct_referal = DirectReferral()
direct_referal.name=....
....
direct_referal.save()
also from your code, it seems that you are assigning string to user object:
DirectReferral.name = username
here username is string and DirectReferral.name is User object. You have to get this user object first and than assign to referral's name.
direct_referal = DirectReferral()
direct_referal.name=User.objects.get(username=username)
....
direct_referal.save()

How to hash text to md5/sha1 in django?

I want to convert text to sha1 in django. But, i'm not find the way how to do it if field attribut wrapped by the form.
This is my views:
def ubah_password_email(request, pk):
#cek session
if 'username' in request.session and request.session['hak_akses'] == 'user':
user = get_object_or_404(User, pk=pk) #ambil id dengan get
profile = UserProfile.objects.filter(user=user).first()
email_form = EmailForm(data=request.POST, instance=profile) #gunakan instance untuk mengambil data yang sudah ada
users = User.objects.all()
if request.POST:
if email_form.is_valid():
email = email_form.save(commit=False)
email.save()
return redirect('home')
else:
email_form = EmailForm(instance=profile)
data = {
'email_form': email_form,
'object_list': users,
}
return render(request, 'ubah_password_email.html', data)
else:
return HttpResponseRedirect('/simofa/logout')
This is my model
class UserProfile(models.Model):
user = models.OneToOneField(User) #digunakan untuk relasi ke model User (default) alias UserProfile adalah sebagai extending model
CATEGORY_CHOICES = (
('admin','Admin'),
('user','User'),
)
hak_akses = models.CharField(max_length=100, choices = CATEGORY_CHOICES)
password_email = models.CharField(max_length=100, blank=True)
password_pckelas = models.CharField(max_length=100, blank=True)
# Override the __unicode__() method to return out something meaningful!
def __unicode__(self):
return self.user.username
This is my forms
class EmailForm(forms.ModelForm):
password_email = forms.CharField(widget=forms.PasswordInput())
class Meta:
model = UserProfile
fields = ('password_email',)
i'm trying using this and this reference. But, i still can't convert text to sha1?
I'm very grateful for your input. So, please help me :)
I'm not sure why you want or need a second password field. But make_password allows you to generate a hashed password:
from django.contrib.auth.hashers import make_password
Docs: https://docs.djangoproject.com/en/1.7/topics/auth/passwords/#django.contrib.auth.hashers.make_password
Source: https://github.com/django/django/blob/master/django/contrib/auth/hashers.py#L58