I am adding in some functionality that allows a user to edit their personal profile page information. When the user updates their info and hit submit they are getting a NameErrorsaying that the user is not defined. Below is how I am trying to implement the editing functionality.
forms
#this is all the information that the user is allowed to edit.
class UpdateProfile(forms.ModelForm):
username = forms.CharField(required=False)
email = forms.EmailField(required=False)
first_name = forms.CharField(required=False)
last_name = forms.CharField(required=False)
age = forms.IntegerField(required=False)
height = forms.IntegerField(required=False)
weight = forms.IntegerField(required=False)
class Meta:
model = User
fields = ('username', 'email', 'first_name', 'last_name', 'age', 'height', 'weight')
def clean_email(self):
username = self.cleaned_data.get('username')
email = self.cleaned_data.get('email')
if email and User.objects.filter(email=email).exclude(username=username).count():
raise forms.ValidationError('This email address is already in use. Please supply a different email address.')
return email
def save(self, commit=True):
# user = super(RegisterUserForm, self).save(commit=False)
user.email = self.cleaned_data['email']
#This is where i am trying to save the new information.
if commit:
user.save()
#This is where i am returning the user.
return user
Views
def update_profile(request):
args = {}
if request.method == 'POST':
form = UpdateProfile(request.POST, instance=request.user)
form.actual_user = request.user
if form.is_valid():
form.save()
return HttpResponseRedirect(reverse('account:profile.html'))
else:
form = UpdateProfile()
args['form'] = form
return render(request, 'account/edit_profile.html', args)
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?
Weird issue with by registration form, not sure i am doing wrong.
I have StudentProfile Model, that I am trying to save data from StudentResistrationForm but the data is not being saved into database
ERROR: NameError at /register/ name 'StudentProfile' is not defined
Is the view logic correct? What am I missing? Ideas please
model
class Accounts(AbstractUser):
email = models.EmailField('email address', unique=True)
first_name = models.CharField('first name', max_length=30, blank=True)
last_name = models.CharField('last name', max_length=30, blank=True)
date_joined = models.DateTimeField('date joined', auto_now_add=True)
# asdd
bio = models.TextField(max_length=500, blank=True)
location = models.CharField(max_length=30, blank=True)
birth_date = models.DateField(null=True, blank=True)
class StudentProfile(models.Model):
user = models.OneToOneField('Accounts', related_name='student_profile')
# additional fields for students
AMEB_Ratings = models.PositiveIntegerField(default=0)
is_student = models.BooleanField('student status', default=False)
form
class StudentResistrationForm(forms.ModelForm):
class Meta:
model = StudentProfile
fields = (
'AMEB_Ratings',
)
def save(self, commit=True):
user = super(StudentResistrationForm, self).save(commit=False)
# user.first_name = self.cleaned_data['first_name']
# user.last_name = self.cleaned_data['last_name']
user.AMEB_Ratings = self.cleaned_data['AMEB_Ratings']
if commit:
user.save()
return user
class UserForm(forms.ModelForm):
class Meta:
model = get_user_model()
fields = ('username', 'email', 'password')
view
def registerStudent(request):
# Once register page loads, either it will send to the server POST data (if the form is submitted), else if it don't send post data create a user form to register
if request.method == "POST":
user_form = UserForm(request.POST)
form = StudentResistrationForm(request.POST)
if form.is_valid() and user_form.is_valid():
User = get_user_model()
username = user_form.cleaned_data['username']
email = user_form.cleaned_data['email']
password = user_form.cleaned_data['password']
new_user = User.objects.create_user(username=username, email=email, password=password)
Student_profile = StudentProfile()
Student_profile.user = new_user
Student_profile.AMEB_Ratings = request.POST['AMEB_Ratings']
# Student_profile = StudentProfile.create_user(AMEB_Ratings=AMEB_Ratings)
new_user.save()
Student_profile.save()
# form.save()
# AMEB_Ratings = form.cleaned_data['AMEB_Ratings']
return redirect('/')
else:
# Create the django default user form and send it as a dictionary in args to the reg_form.html page.
user_form = UserForm()
form = StudentResistrationForm()
# args = {'form_student': form, 'user_form': user_form }
return render(request, 'accounts/reg_form_students.html', {'form_student': form, 'user_form': user_form })
Looks like you have a few typos you currently are setting your email variable to the email data then setting it to the password data. Correct this first.
email = user_form.cleaned_data['email']
password = user_form.cleaned_data['password']
I have a model with a field called in is_student and is_teacher Student and Teacher forms
is_teacher = models.BooleanField('teacher status', default=False)
is_student = models.BooleanField('student status', default=False)
I want to make sure this field is:
Always Checked by the user True *Required
Currently: is_teacher in TeacherApplications Model
When unchecked - it saved 0 to the form and continues. (Not good)
When checked gives me this error:
ValueError at /register/teacher invalid literal for int() with base
10: ''
Currently: is_student in StudentProfile Model
When checked gives this error
ValidationError at /register/ ["'on' value must be either True or
False."]
When unchecked it saved 0 to the form and continues. (Again, not good)
UPDATED CODE
Above errors are gone: New error each time I try to submit form after checking is_teacher/is_student
IntegrityError at /register/ NOT NULL constraint failed:
accounts_studentprofile.is_student
model
class StudentProfile(models.Model):
user = models.OneToOneField('Accounts', related_name='student_profile')
# additional fields for students
AMEB_Ratings = models.PositiveIntegerField(default=0)
is_student = models.BooleanField('student status', default=False)
class TeacherApplications(models.Model):
user = models.OneToOneField('Accounts', related_name='teacher_profile')
# additional fields for teachers
instrument = models.TextField(max_length=500, blank=True)
skill = models.CharField(max_length=30, blank=True)
experience_in_years = models.PositiveIntegerField(blank=True)
is_teacher = models.BooleanField('teacher status', default=False)
view
def registerStudent(request):
# Once register page loads, either it will send to the server POST data (if the form is submitted), else if it don't send post data create a user form to register
if request.method == "POST":
user_form = UserForm(request.POST)
form = StudentResistrationForm(request.POST)
if form.is_valid() and user_form.is_valid():
User = get_user_model()
username = user_form.cleaned_data['username']
email = user_form.cleaned_data['email']
password = user_form.cleaned_data['password']
new_user = User.objects.create_user(username=username, email=email, password=password)
student = form.save(commit=False)
student.user = new_user
student.save()
# Student_profile = StudentProfile()
# Student_profile.user = new_user
# Student_profile.AMEB_Ratings = request.POST['AMEB_Ratings']
# Student_profile.is_student = request.POST.get('is_student', False)
new_user.save()
# Student_profile.save()
# form.save()
return redirect('/')
else:
# Create the django default user form and send it as a dictionary in args to the reg_form.html page.
user_form = UserForm()
form = StudentResistrationForm()
# args = {'form_student': form, 'user_form': user_form }
return render(request, 'accounts/reg_form_students.html', {'form_student': form, 'user_form': user_form })
def teacherApplication(request):
# Once register page loads, either it will send to the server POST data (if the form is submitted), else if it don't send post data create a user form to register
if request.method == "POST":
user_form = UserForm(request.POST)
form = TeacherRegistrationForm(request.POST)
if form.is_valid() and user_form.is_valid():
User = get_user_model()
username = user_form.cleaned_data['username']
email = user_form.cleaned_data['email']
password = user_form.cleaned_data['password']
new_user = User.objects.create_user(username=username, email=email, password=password)
teacher = form.save(commit=False)
teacher.user = new_user
teacher.save()
# Teacher_profile = TeacherApplications()
# Teacher_profile.user = new_user
# Teacher_profile.instrument = request.POST['instrument']
# Teacher_profile.skill = request.POST['skill']
# Teacher_profile.experience_in_years = request.POST['experience_in_years']
# Teacher_profile.is_teacher = request.POST.get('is_teacher', False)
new_user.save()
# Teacher_profile.save()
# form.save()
return redirect('/')
else:
# Create the django default user form and send it as a dictionary in args to the reg_form.html page.
user_form = UserForm()
form = TeacherRegistrationForm()
return render(request, 'accounts/reg_form_teachers.html', {'form_student': form, 'user_form': user_form })
forms
class StudentResistrationForm(forms.ModelForm):
class Meta:
model = StudentProfile
fields = (
'AMEB_Ratings',
'is_student',
)
def save(self, commit=True):
user = super(StudentResistrationForm, self).save(commit=False)
# user.first_name = self.cleaned_data['first_name']
# user.last_name = self.cleaned_data['last_name']
user.AMEB_Ratings = self.cleaned_data['AMEB_Ratings']
if commit:
user.save()
return user
class TeacherRegistrationForm(forms.ModelForm):
class Meta:
model = TeacherApplications
fields = (
'instrument',
'skill',
'experience_in_years',
'is_teacher',
)
class UserForm(forms.ModelForm):
class Meta:
model = get_user_model()
fields = ('username', 'email', 'password')
You can add this fields to StudentResistrationForm and TeacherRegistrationForm and add custom validation for it in clean_fieldname method to make it required:
StudentResistrationForm(ModelForm):
class Meta:
model = StudentRegistration
fields = (
'instrument',
'skill',
'experience_in_years',
'is_student',
)
def clean_is_student(self):
is_student = self.cleaned_data.get('is_student')
if not is_student:
raise forms.ValidationError('This field is required')
return is_student
Also in view instead of getting raw data from request.POST you can use forms to create student and teacher objects:
new_user = User.objects.create_user(username=username, email=email, password=password)
teacher = form.save(commit=False)
teacher.user = new_user
teacher.save()
I am trying to allow users the ability to update their profile, but can't seem to figure out how to only raise an error if the 2 fields username, email were modified, or if the user is not that user. As of now, I can't save the updates as the error is continuously popping up since the user has those values obviously. I've also tried excludes but couldn't get it to work right either. Here is my code:
forms.py
class UpdateUserProfile(forms.ModelForm):
first_name = forms.CharField(
required=True,
label='First Name',
max_length=32,
)
last_name = forms.CharField(
required=True,
label='Last Name',
max_length=32,
)
email = forms.EmailField(
required=True,
label='Email (You will login with this)',
max_length=32,
)
username = forms.CharField(
required = True,
label = 'Display Name',
max_length = 32,
)
class Meta:
model = User
fields = ('username', 'email', 'first_name', 'last_name')
def clean_email(self):
email = self.cleaned_data.get('email')
username = self.cleaned_data.get('username')
if (User.objects.filter(username=username).exists() or User.objects.filter(email=email).exists()):
raise forms.ValidationError('This email address is already in use.'
'Please supply a different email address.')
return email
def save(self, commit=True):
user = super().save(commit=False)
user.email = self.cleaned_data['email']
user.username = self.cleaned_data['username']
if commit:
user.save()
return user, user.username
views.py
def update_user_profile(request, username):
args = {}
if request.method == 'POST':
form = UpdateUserProfile(request.POST, instance=request.user)
if form.is_valid():
form.save()
return HttpResponseRedirect(reverse('user-profile', kwargs={'username': form.save()[1]}))
else:
form = UpdateUserProfile(instance=request.user)
args['form'] = form
return render(request, 'storytime/update_user_profile.html', args)
Just check if another user exists by excluding the current one:
from django.db.models import Q
class UpdateUserProfile(forms.ModelForm):
# ...
def clean_email(self):
# ...
if User.objects.filter(
Q(username=username)|Q(email=email)
).exclude(pk=self.instance.pk).exists():
raise ...
# for checking if both were modified
if self.instance.email != email and self.instance.username != username:
raise ...
One could further argue that this code belongs in the form's clean method as it validates field interdependencies.
Upon signup, I'd like to request the user for:
Full name (I want to save it as first and last name though)
Company name
Email
Password
I've read through dozens of similar situations on StackOverflow. In models.py, I extend the User model like so:
# models.py
class UserProfile(models.Model):
company = models.CharField(max_length = 50)
user = models.OneToOneField(User)
def create_user_profile(sender, instance, created, **kwargs):
if created:
profile, created = UserProfile.objects.get_or_create(user=instance)
post_save.connect(create_user_profile, sender=User)
Source: Extending the User model with custom fields in Django
I've also added:
# models.py
class SignupForm(UserCreationForm):
fullname = forms.CharField(label = "Full name")
company = forms.CharField(max_length = 50)
email = forms.EmailField(label = "Email")
password = forms.CharField(widget = forms.PasswordInput)
class Meta:
model = User
fields = ("fullname", "company", "email", "password")
def save(self, commit=True):
user = super(SignupForm, self).save(commit=False)
first_name, last_name = self.cleaned_data["fullname"].split()
user.first_name = first_name
user.last_name = last_name
user.email = self.cleaned_data["email"]
if commit:
user.save()
return user
And in views.py:
# views.py
#csrf_exempt
def signup(request):
if request.method == 'POST':
form = SignupForm(request.POST)
if form.is_valid():
new_user = form.save()
first_name, last_name = request.POST['fullname'].split()
email = request.POST['email']
company = request.POST['company'],
new_user = authenticate(
username = email,
password = request.POST['password']
)
# Log the user in automatically.
login(request, new_user)
Right now, it doesn't store the company name. How do I do that?
user_profile = new_user.get_profile()
user_profile.company = company
user_profile.save()
Don't forget to configure your UserProfile class in settings so Django knows what to return on user.get_profile()