I have default Django registration form. It is sent to render to the page based on type of request and user login status. This logic is implemented in views.py file. Somehow, if user is not logged in and GET request is sent to the page, my view returns UnboundLocalError: local variable 'form' is referenced before assignment. How could this happen?
P.S. Here's my view.
def EmplRegisterView(request):
if request.method == 'POST':
form = UserCreationForm(request.POST)
if form.is_valid():
user = form.save()
group = Group.objects.get(name = 'Employers')
user.groups.add(group)
login(request, user)
return redirect('ProfileSetup')
else:
if request.user.is_authenticated:
logout(request)
form = UserCreationForm()
else:
form = UserCreationForm()
context = {
'form':form,
}
return render(request, "registerPage.html", context)
Try this way
def EmplRegisterView(request):
form = UserCreationForm()
if request.method == 'POST':
form = UserCreationForm(request.POST)
if form.is_valid():
user = form.save()
group = Group.objects.get(name = 'Employers')
user.groups.add(group)
login(request, user)
return redirect('ProfileSetup')
if request.user.is_authenticated:
logout(request)
context = {
'form':form,
}
return render(request, "registerPage.html", context)
Related
How can I solve this in Django?
UnboundLocalError at / local variable 'form' referenced before assignment.
def home(request):
if request.user.is_authenticated:
form = MeepForm(request.POST or None)
if request.method == "POST":
if form.is_valid():
meep = form.save(commit=False)
meep.user = request.user
meep.save()
messages.success(request,('Meep has been posted'))
return redirect('home')
meeps = Meep.objects.all().order_by("-created_at")
return render(request, 'home/home.html', {'meeps':meeps,'form':form})
else:
meeps = Meep.objects.all().order_by("-created_at")
return render(request, 'home/home.html', {'meeps':meeps,'form':form})
Just use logic that is written similar to Django MVP views - you can just initialize the form before and then override it when it's needed with POST data.
def home(request):
form = MeepForm()
if request.user.is_authenticated:
if request.method == 'POST':
form = MeepForm(request.POST or None)
if form.is_valid():
meep = form.save(commit=False)
meep.user = request.user
meep.save()
messages.success(request, 'Meep has been posted')
return redirect('home')
meeps = Meep.objects.all().order_by("-created_at")
return render(request, 'home/home.html', {'meeps': meeps,'form': form})
The error is because of the form variable that is being referenced before it is assigned a value. In the case where the user is not authenticated, the form variable is not defined, and so you get the UnboundLocalError, try this:
def home(request):
if request.user.is_authenticated:
if request.method == 'POST':
form = MeepForm(request.POST)
if form.is_valid():
meep = form.save(commit=False)
meep.user = request.user
meep.save()
messages.success(request, 'Meep has been posted')
return redirect('home')
else:
return redirect("some_error_page")
form = MeepForm()
meeps = Meep.objects.all().order_by("-created_at")
return render(request, 'home/home.html', {'meeps': meeps,'form': form})
If your code goes into else, then you wouldn't have initialized a form object and hence the error.
else:
meeps = Meep.objects.all().order_by("-created_at")
return render(request, 'home/home.html', {'meeps':meeps,'form':form})
Here u wouldn't be having form. So initialize it here - inside else or have some value before if.
I have 2 user types, teacher and student. I have built the view to be able to edit a student profile. But I also needed a different one for teacher. I didn't want 2 views, because that would be pointless. Now, for teacher it works as intended, but for some reason for student, the same form as for teacher is displayed... a student has different attributes so it has a different form I need to show.
#login_required
def profile_edit(request):
user = request.user
student = request.user.student
teacher = request.user.teacher
if user == teacher.user:
if request.method != 'POST':
form = TeacherEditForm(instance=teacher)
else:
form = TeacherEditForm(request.POST, instance=teacher)
if form.is_valid():
user.email = form.cleaned_data['email']
user.save()
form.save()
return redirect('index')
elif user == student.user:
if request.method != 'POST':
form = StudentEditForm(instance=student)
else:
form = StudentEditForm(request.POST, instance=student)
if form.is_valid():
user.email = form.cleaned_data['email']
user.save()
form.save()
return redirect('index')
context = {
"form": form,
}
return render(request, "registration/profile_edit.html", context)
I think there is something wrong with the way I pass data to student and teacher and the view can't differentiate between user types.
Something like this but remove
User.student = property(lambda p: Student.objects.get_or_create(user=p)[0])
User.teacher = property(lambda p: Teacher.objects.get_or_create(user=p)[0])
#login_required
def profile_edit(request):
user = request.user
try:
student = Student.objects.get(user=user)
s=True
except: teacher = Teacher.objects.get(user=user)
if not s:
if request.method != 'POST':
form = TeacherEditForm(instance=teacher)
else:
form = TeacherEditForm(request.POST, instance=teacher)
if form.is_valid():
user.email = form.cleaned_data['email']
user.save()
form.save()
return redirect('index')
elif s:
if request.method != 'POST':
form = StudentEditForm(instance=student)
else:
form = StudentEditForm(request.POST, instance=student)
if form.is_valid():
user.email = form.cleaned_data['email']
user.save()
form.save()
return redirect('index')
context = {
"form": form,
}
return render(request, "registration/profile_edit.html", context)
I want to redirtect page, after saving modelform. when i pushed save button, page redirecte, but no any things saved.
def channelAdd(request):
if request.method == 'POST':
form = ChannelForm(request.POST)
if form.is_valid():
channelid = form.cleaned_data['channelid']
form.save()
return HttpResponseRedirect(reverse('updateChannelInfo', args=[channelid]))
else:
form = ChannelForm()
return render(request, 'web/channelAdd.html', {'form':form})
This will get you closer to the solution. I'm not positive if you have 'updateChannelInfo' as the name in urls.py (so please double-check that). I think the complexity here is getting the correct channelId to be sent
def channelAdd(request):
if request.method == 'POST':
form = ChannelForm(request.POST)
if form.is_valid():
channelid = form.cleaned_data['channelid']
form.save()
return HttpResponseRedirect(reverse('updateChannelInfo', args = [self.object.id])))
else:
form = ChannelForm()
return render(request, 'web/channelAdd.html', {'form':form})
If you are willing to share your urls.py and forms.py files, this would help with getting the correct names into arguments
Another way I have had success with the dynamic direct after form submission is to use
def add_channel (request):
if request.method == 'POST':
form = ChannelForm(request.POST)
if form.is_valid():
channel.save()
return HttpResponseRedirect(reverse('channel_detail', args=[channel.id]))
else:
form = ChannelForm()
return render(request, 'channel_example.html', {'form': form})
Edit your view like this,
if form.is_valid():
form.save()
return redirect('updateChannelInfo', channelId=self.object.id)
I am changing the password if the current user is logged in.
views.py:
def change_password(request,pk=None):
user = MyUser.objects.get(pk=pk)
if request.method == "POST":
form = PasswordChangeForm(user=user, data=request.POST)
if form.is_valid():
form.save()
update_session_auth_hash(request, form.user)
context = {
'form': form,
'title': _('Password change'),
}
return render(request, "nurse/change_password.html")
else:
form = PasswordChangeForm(user=user)
context = {
'form': form,
'title': _('Password change'),
}
return render(request,"nurse/change_password.html")
The function is working fine, but after this function call, I am not getting user.id in my html file.
What am I doing wrong?
I have a Django form that allows a user to save their UserProfile details, but it only allows this to occur once. Given that additional saves ask to create a new entry, but i have a one-to-one relation between the user field and user UserProfile field.
When a user is created a UserProfile entry is not created. Rather they cannot access their account until these details are filled out.
I want to pre-populate the form with existing data when a student goes to access the form a second time.
def student_details(request):
#this is a form
if request.user.is_authenticated():
if request.method == 'POST':
form = DetailsForm(request.user, request.POST, request.FILES)
if form.is_valid():
note = form.save(commit=False)
note.user = request.user
note.completed_form = True
note.save()
return HttpResponseRedirect('/student-portal/')
else:
if request.user.get_profile():
pass
form = DetailsForm(request.user)
else:
form = DetailsForm(request.user)
return render_to_response("student-details.html", {'form': form}, context_instance=RequestContext(request))
return HttpResponseRedirect('/')
Sorry guys just found out how to do this:
def student_details(request):
#this is a form
if request.user.is_authenticated():
if request.method == 'POST':
form = DetailsForm(request.user, request.POST, request.FILES)
if form.is_valid():
note = form.save(commit=False)
user_profile = UserProfile.objects.get(user=request.user)
if user_profile:
note.id = user_profile.id
note.user = request.user
note.completed_form = True
note.save()
return HttpResponseRedirect('/student-portal/')
else:
try:
user_profile = UserProfile.objects.get(user=request.user)
form = DetailsForm(request.user, instance=user_profile)
except:
form = DetailsForm(request.user)
return render_to_response("student-details.html", {'form': form}, context_instance=RequestContext(request))
return HttpResponseRedirect('/')
The idea here is to query to see if a user_profile linked to that user already exists and then specify the ID for that entry.