i want to extend my User models and add fields to it in another models
and i want it to save two of the form at once
each form works fine on its own but
the problem is that when i combine them the
i cant get the username from the User model
class Information(models.Model):
Username = models.OneToOneField(User, on_delete=models.CASCADE)
i tried this views.py
RegisterForm = self.form_class(request.POST)
InfoForm = self.second_form_class(request.POST)
if RegisterForm.is_valid() and InfoForm.is_valid():
username = request.POST.get('username')
password = request.POST.get('password')
email = request.POST.get('email')
first_name = request.POST.get('first_name')
last_name = request.POST.get('last_name')
User_obj = User(username=username, password=password, email=email, first_name=first_name,
last_name=last_name)
user = User_obj.save()
Username = username
PhoneNo = request.POST.get('PhoneNo')
Address = request.POST.get('Address')
Country = request.POST.get('Country')
Info_obj = Information(Username=Username , PhoneNo=PhoneNo, Address=Address, Country=Country)
Info_obj.save()
forms.py
class RegisterForm(forms.ModelForm):
username = forms.CharField(max_length=40)
password = forms.CharField(widget=forms.PasswordInput())
class Meta:
model = User
fields = ["username","password", "email", "first_name", "last_name"]
class InfoForm(forms.ModelForm):
Username = forms.CharField(max_length=40, required=False)
class Meta:
model = Information
fields = ["Username","PhoneNo","Address","Country"]
did i miss something here?
it can save to the User but it doesn't save to Information model
I think the problem is with the Username on InfoForm
the problem was with the InfoForm's Username field
instead of directly getting the value from the RegisterForm
username = request.POST.get('username')
# with this code below Django demands that i need username instance from User model
Username = username
so after saving RegisterForm, i get the value from the User Database with a objects.get() method
Username = User.objects.get(username=username)
Solution
RegisterForm = self.form_class(request.POST)
InfoForm = self.second_form_class(request.POST)
if RegisterForm.is_valid() and InfoForm.is_valid():
username = request.POST.get('username')
password = request.POST.get('password')
email = request.POST.get('email')
first_name = request.POST.get('first_name')
last_name = request.POST.get('last_name')
User_obj = User(username=username, password=password, email=email, first_name=first_name,
last_name=last_name)
User_obj.save()
# i call the username from the User database after saving them
Username = User.objects.get(username=username)
PhoneNo = request.POST.get('PhoneNo')
Address = request.POST.get('Address')
Country = request.POST.get('Country')
Info_obj = Information(Username=Username , PhoneNo=PhoneNo, Address=Address, Country=Country)
Info_obj.save()
don't know if i had explained it correctly
Cheers
Related
I have made a form having fields of personal information and login information as one
models.py
class EmployeeModel(models.Model)
employee_id = models.CharField(max_length=300,unique=True,help_text='Employee ID should not be same')
name = models.CharField(max_length=300)
username = models.CharField(max_length=50,null=True,blank=True)
email = models.EmailField(null=True,blank=True)
password = models.CharField(max_length=20,null=True,blank=True)
password_confirm = models.CharField(max_length=20,null=True,blank=True)
forms.py
class EmployeeForm(forms.ModelForm):
class Meta:
model = employeeModel
fields = ('__all__')
views.py
User = get_user_model()
def create_view(request):
if request.method == 'POST':
form = employeeForm(request.POST or None,request.FILES or None)
if form.is_valid():
username = form.cleaned_data['username']
email = form.cleaned_data['email']
password = form.cleaned_data['password']
User= get_user_model()
user= User.objects.create_user(username=username,email=email,password=password)
authenticate(request,username=username,email=email,password=password)
form.save()
return redirect('emp_list')
else:
form = employeeForm()
return render(request,'create_employee.html',{'form':form})
Its not showing any error but User.objects.all() shows only superuser not the users i created though this form. Those users i have created in this form are are showing up in Employee.objects.get(username='foo')
So what to do? I cant login through those non_superusers. it throws invalid login error. How to fix this?
So I'm trying to use the authentication method in my views, but always return "Does not exist", I'm using MD5 hash for my password field, so I don't know if thats the problem
forms.py
class LoginForm(forms.Form):
email = forms.EmailField()
password = forms.CharField(widget=forms.PasswordInput)
#This Method Hash the password
def clean_password(self):
clearPassNoHash = self.cleaned_data['password']
self.password = md5.new(clearPassNoHash).hexdigest()
return self.password
views.py
def auth_login(request):
args = {}
form = LoginForm(request.POST)
email = request.POST['email']
password = request.POST['password']
user = authenticate(email=email, password=password)
if user is not None:
login(request, user)
print("Exist")
else:
print("Does not exist")
I've tried with check_password() method(in my forms) that actually works
but I don't know why I'm having trouble with the authenticate()
-----------------------------UPDATE--------------------------------
Views.py
def auth_login(request):
args = {}
form = LoginForm(request.POST)
if form.is_valid():
username = form.cleaned_data['username']
password = form.cleaned_data['password']
user = authenticate(username=username, password=password)
if user is not None:
print("existe")
print user
else:
print user
args['form'] = form
return render(request, 'login/login.html', args)
forms.py
class LoginForm(forms.Form):
username = forms.CharField()
password = forms.CharField(widget=forms.PasswordInput)
Other observation:
I have this in my settings.py to use my custom model
AUTH_PROFILE_MODULE = 'StudentUsers.StudentRegistration'
and this is the username field I add to my model:
class StudentRegistration(AbstractBaseUser, models.Model):
username = models.CharField(max_length = 25, null=False, default="", unique=True)
You need to get the email and password from the form's cleaned_data, not from the request directly. Read more on the cleaned_data attribute from the docs : https://docs.djangoproject.com/en/1.9/ref/forms/api/#django.forms.Form.cleaned_data
password = form.cleaned_data['password']
You should not be hashing the password value yourself. That is what authenticate already does; so in effect you are hashing twice.
I have a UserProfile model to add some things to my User model and one thing I want to do is have unique email for users so I added an email attribute to my UserProfile model and set it to unique=True like this :
class UserProfile(models.Model):
user = models.OneToOneField(User, related_name="profile")
email = models.EmailField(unique=True)
avatar = models.ForeignKey(Avatar)
...
I created a custom form for the registration to add some infos directly to my UserProfile :
class CreateUserForm(forms.Form):
username = forms.CharField(max_length=30, label="Pseudo")
password1 = forms.CharField(widget=forms.PasswordInput, label="Password")
password2 = forms.CharField(widget=forms.PasswordInput, label="Confirmez pwd")
email = forms.EmailField(widget=forms.EmailInput, label="E-mail")
avatar = AvatarChoiceField(widget=forms.RadioSelect, queryset=Avatar.objects.all(), label="Avatar")
def clean_username(self):
username = self.cleaned_data.get('username')
if User.objects.filter(username=username).exists():
raise forms.ValidationError("This username is already used")
return username
def clean_password2(self):
password1 = self.cleaned_data.get('password1')
password2 = self.cleaned_data.get('password2')
if password1 != password2:
raise forms.ValidationError("Your passwords do not match")
return password1
def clean_email(self):
email = self.cleaned_data.get('email')
if UserProfile.objects.filter(email=email).exists():
raise forms.ValidationError("This email is already used")
return email
And then in my views.py I treat my form like that :
def create_user(request):
if request.method == 'POST':
form = CreateUserForm(request.POST)
if form.is_valid():
username = form.clean_username()
email = form.clean_email()
password = form.clean_password2()
username = form.cleaned_data['username']
avatar = form.cleaned_data['avatar']
user = User.objects.create_user(username=username, password=password)
user.save()
user_profile = UserProfile(user=user, email=email, avatar=avatar)
user_profile.save()
else:
form = CreateUserForm()
return render(request, 'accounts/create.html', locals())
Finally I used the email of the form for my UserProfile model and not for my User model. And by this way I have a unique email for my users. And it's working.
Am I doing it right or is there a better way to achieve what I want ?
You are on the right track, the only thing that doesn't look right is that you shouldn't call clean method manually like this:
# These are not needed in your view method
username = form.clean_username()
email = form.clean_email()
password = form.clean_password2()
They are already called by form.is_valid(). See this SO question for details.
I have a user in my database with the login jim#test.com and password jimrox. I'm trying to log him in with this view:
def login(request):
email = request.POST.get("email", "")
password = request.POST.get("password", "")
user = authenticate(username=email, password=password)
My custom authentication looks partly like this:
class login(object):
def authenticate(self, username=None, password=None):
# auth user based on email
try:
user = Freelancer.objects.get(email=username)
if user.check_password(password):
return user
except User.DoesNotExist:
return None
When the user attempts to check_password() it doesn't return the user even though the password is correct. Am I meant to create my own check_password() function in the model?
Here is my model also:
class FreelancerManager(BaseUserManager):
def create_user(self, email, date_of_birth, password=None):
"""
Creates and saves a User with the given email, date of
birth and password.
"""
if not email:
raise ValueError('Users must have an email address')
user = self.model(
email=self.normalize_email(email),
date_of_birth=date_of_birth,
)
user.set_password(password)
user.save(using=self._db)
return user
class Freelancer(AbstractBaseUser):
email = models.EmailField()
first_name = models.CharField(max_length=128, primary_key=True)
surname = models.CharField(max_length=128)
university = models.CharField(max_length=256)
verified = models.BooleanField(default=False)
created_date = models.DateTimeField(default=timezone.now)
USERNAME_FIELD = 'email'
If I am meant to create my own password check, how would I do that? This is with 1.8 also.
EDIT
Here is how I add my users to the database:
views.py
def freelancer_signup(request):
if request.method == 'POST':
form = FreelancerForm(request.POST)
if form.is_valid():
freelancer = form.save(commit=False)
freelancer.save()
return render(request, 'freelancestudent/index.html')
else:
return render(request, 'freelancestudent/index.html')
else:
form = FreelancerForm()
return render(request, 'freelancestudent/freelancersignup.html', {'form': form})
forms.py
from django import forms
from models import Freelancer
class FreelancerForm(forms.ModelForm):
class Meta:
model = Freelancer
password = forms.CharField(widget=forms.PasswordInput)
fields = ('email', 'first_name', 'surname', 'university', 'password')
Here it's my django model
class student(User):
name = models.CharField(max_length = 200)
phone_no = models.BigIntegerField()
email_id = models.EmailField()
version = models.IntegerField()
now I want to register user that are extend by my model fields.
here its my student register code
def registerStudent(request):
print request.body
if request.body:
dataDictionary = json.loads(request.body)
username = dataDictionary['username']
first_name = dataDictionary['first_name']
last_name = dataDictionary['last_name']
email = dataDictionary['email']
password = dataDictionary['password']
password1 = dataDictionary['password1']
user=User()
user.username = username
user.first_name = first_name
user.last_name = last_name
user.email = email
if password == password1:
user.set_password(password)
else:
return HttpResponse(json.dumps([{"validation": "Password does not match", "status": False}]), content_type="application/json")
user.save()
here something wrong
I want to take json as a input and create user using above model field.
I seems that you only save the user when the passwords don't match, after the return. Move the "user.save()" line one tab to the left.
The code should be:
if password == password1:
user.set_password(password)
user.save()
else:
return HttpResponse(json.dumps([{"validation": "Password does not match"
,"status": False}])
,content_type="application/json")
Now the user will be saved when password = password1, if that what you want.