AttributeError at /basic_app/register/ : 'tuple' object has no attribute 'get' - django

I know this question have been asked alot and most of the time its due to render or HttpResponse in the views.py, i double checked mine but the code looks good to me, dont know where the problem is.
This is a views.py file for a very basic django form but i can't get it to work
def register(request):
registered = False
if request.method == 'POST':
user_form = UserForm(data = request.POST)
profile_form = UserProfileInfoForm(data = request.POST)
if user_form.is_valid() and profile_form.is_valid():
user = user_from.save()
user.set_password(user.password)
user.save()
profile = profile_form.save(commit = False)
profile.user = user
if 'profile_pic' in request.FILES:
profile.profile_pic = request.FILES['profile_pic']
profile.save()
registered = True
else:
return (user_form.errors,profile_form.errors)
else:
user_form = UserForm()
profile_form = UserProfileInfoForm()
return render(request,'basic_app/register.html',{'user_form': user_form,
'profile_form':profile_form,
'registered':registered})

You can not return (user_form.errors, profile_form.errors), since that is not a HttpResponse object. What response should the server return in that case.
Usually in case the form is invalid, the server will rerender the content. The form will, if you render it properly display the errors.
Note that in case the POST request was successful, you usually should redirect to implement the Post/Redirect/Get pattern [wiki]. You furthermore probably want to use a UserCreationForm [Django-doc]. This will set the password of the user in the correct way (with .set_password(..)), and run a password validator if you configured this.
You thus can rewrite your view as follows, but you probably should replace UserForm with UserCreationForm:
from django.shortcuts import redirect
def register(request):
if request.method == 'POST':
user_form = UserForm(data=request.POST)
profile_form = UserProfileInfoForm(data=request.POST)
if user_form.is_valid() and profile_form.is_valid():
user = user_from.save(commit=False)
user.set_password(user.password)
user.save()
profile = profile_form.save(commit=False)
profile.user = user
if 'profile_pic' in request.FILES:
profile.profile_pic = request.FILES['profile_pic']
profile.save()
return redirect('name-of-view')
else:
user_form = UserForm()
profile_form = UserProfileInfoForm()
return render(
request,
'basic_app/register.html',
{'user_form': user_form, 'profile_form':profile_form })

Related

Why am I getting the error local variable 'user_form' referenced before assignment

In the code, why am I getting "local variable 'user_form' referenced before assignment" error?
from django.shortcuts import render
from basic_app.forms import UserForm,UserProfileInfoForm
def index(request):
return render(request,'basic_app/index.html')
def register(request):
registered=False
if request.method=="POST":
user_form=UserForm(data=request.POST)
profile_form=UserProfileInfoForm(data=request.POST)
if user_form.is_valid() and profile_form.is_valid():
user=user_form.save()
user.set_password(user.password) #Hashing the password
user.save()
profile=profile_form.save(commit=False)
profile.user=user #Sets up one to one relationship
if 'profile_pic' in request.FILES:
profile.profile_pic=request.FILES['profile_pic']
profile.save()
registered=True
else:
print(user_form.errors,profile_form.errors)
else:
user_form=UserForm()
profile_form=UserProfileInfoForm()
return render(request,'basic_app/registration.html',{'user_form':user_form,'profile_form':profile_form,'registered':registered})
This is in the views.py file.
Have been stuck on this project since a while. Please help?
Your second else block is indented too far. Move it back one level.
You have indenting issue.. Check the edited one here
from django.shortcuts import render
from basic_app.forms import UserForm, UserProfileInfoForm
def index(request):
return render(request, 'basic_app/index.html')
def register(request):
registered = False
if request.method == "POST":
user_form = UserForm(data=request.POST)
profile_form = UserProfileInfoForm(data=request.POST)
if user_form.is_valid() and profile_form.is_valid():
user = user_form.save()
user.set_password(user.password) # Hashing the password
user.save()
profile = profile_form.save(commit=False)
profile.user = user # Sets up one to one relationship
if 'profile_pic' in request.FILES:
profile.profile_pic = request.FILES['profile_pic']
profile.save()
registered = True
else:
print(user_form.errors, profile_form.errors)
else:
user_form = UserForm()
profile_form = UserProfileInfoForm()
return render(request, 'basic_app/registration.html', {'user_form': user_form, 'profile_form': profile_form, 'registered': registered})

The view account.views.register didn't return an HttpResponse object

Good day everyone, i'm new to django, i'm working on a project were users can create accounts, i'm using the django registration model. Here's the problem,during registration, if the username the guest wants to use is taken or the passwords entered don't match, it gives this error 'The view account.views.register didn't return an HttpResponse object. It returned None instead.' instead of informing the guest about the errors.
views.py
def register(request):
if request.method == 'POST':
user_form = UserRegistrationForm(request.POST)
if user_form.is_valid():
# Create a new user object but avoid saving it yet
new_user = user_form.save(commit=False)
# # Set the chosen password
new_user.set_password(
user_form.cleaned_data['password'])
# Save the User object
new_user.save()
profile = Profile.objects.create(user=new_user)
return render(request, 'account/register_done.html', {'new_user': new_user})
else:
user_form = UserRegistrationForm()
return render(request, 'account/register.html', {'user_form': user_form})
As Selcuk suggested in the comment, add an else clause in your views as below,
from django.http import HttpResponse
def register(request):
if request.method == 'POST':
user_form = UserRegistrationForm(request.POST)
if user_form.is_valid():
# Create a new user object but avoid saving it yet
new_user = user_form.save(commit=False)
# # Set the chosen password
new_user.set_password(
user_form.cleaned_data['password'])
# Save the User object
new_user.save()
profile = Profile.objects.create(user=new_user)
return render(request, 'account/register_done.html', {'new_user': new_user})
else: # form is not valid
return HttpResponse("Form is not valid")
else:
user_form = UserRegistrationForm()
return render(request, 'account/register.html', {'user_form': user_form})

RelatedObjectDoesNOTExist-Edit profile

Django==1.10.5. I have a problem RelatedObjectDoesNotExist
Views.py:
def register(request):
if request.method == 'POST':
user_form = UserRegistrationForm(request.POST)
if user_form.is_valid():
# Create a new user object but avoid saving it yet
new_user = user_form.save(commit=False)
# Set the chosen password
new_user.set_password(user_form.cleaned_data['password'])
# Save the User object
new_user.save()
# Create the user profile
profile = Profile.objects.create(user=new_user)
return render(request,
'account/register_done.html',
{'new_user': new_user})
else:
user_form = UserRegistrationForm()
return render(request, 'account/register.html', {'user_form': user_form})
and
#login_required
def edit(request):
if request.method == 'POST':
user_form = UserEditForm(instance=request.user,
data=request.POST)
profile_form = ProfileEditForm(instance=request.user.profile,
data=request.POST,
files=request.FILES)
if user_form.is_valid() and profile_form.is_valid():
user_form.save()
profile_form.save()
else:
user_form = UserEditForm(instance=request.user)
profile_form = ProfileEditForm(instance=request.user.profile)
return render(request, 'account/edit.html', {'user_form': user_form,
'profile_form': profile_form})
The problem is that:
profile_form = ProfileEditForm(instance=request.user.profile)
I have similar experience working on this particular exercise.
The error is coming right from code below
Profile_form = ProfileForm(request.POST, instance=request.user.profile)
We are trying to get "request.user.profile" not realizing "User" in the model doesn't have a "profile" but a Profile has a"User" . Therefore a better way to get the "profile":
profile = Profile(user=request.user)
Hence your edit method should look close to this:
#login_required
def edit(request):
profile = Profile(user=request.user)
if request.method == 'POST':
user_form = UserEditForm(instance=request.user,data=request.POST)
profile_form = ProfileEditForm(instance=profile,
data=request.POST,
files=request.FILES)
if user_form.is_valid() and profile_form.is_valid():
user_form.save()
profile_form.save()
messages.success(request, 'Profile updated successfully')
else:
messages.success(request, 'Error updating your profile')
user_form = UserEditForm(instance=request.user)
profile_form = ProfileEditForm(instance=profile)
return render(request,
'accounts/edit.html',
{'user_form': user_form,
'profile_form': profile_form})
Just to answer this question, this code is a snippet from the Django By Example book from the project Building a Social Website.
I encountered the same error when I clicked on the edit your profile link in the dashboard.
So, to solve this error, if you are logged in as a superuser, then go to the admin site of your project (url: localhost/admin/) and then under the Account heading, click on Profiles and click the Add profile link on the top right corner. Select the user from the dropdown, add the profile details and click save.
Now going back to the dashboard and clicking the edit your profile link should display the desired view.
I tried another alternative this scenario is that when we update our code we have some users that registered but not have a profile. I deleted the users and in admin and signed up with account it worked
but you will have a problem when logging with facebook

Render in django can't passing an argument

i'm new in django and i'm trying to create an application that user can change his/her password based on his/her id. So far is good, but when i'm trying to passing an argument from my views.py, there is a trouble that an argument can't passing to the html template.
This is my views:
def tambah_user(request, template_name='form_user.html'):
if 'username' in request.session:
username = User.objects.all()
data = {}
data['object_list'] = username
if request.method == 'POST':
user_form = UserForm(data=request.POST)
profile_form = UserProfileForm(data=request.POST)
if user_form.is_valid() and profile_form.is_valid():
user = user_form.save()
user.set_password(user.password)
user.save()
profile = profile_form.save(commit=False)
profile.user = user
profile.save()
return redirect('manajemen_user')
else:
print user_form.errors, profile_form.errors
else:
user_form = UserForm()
profile_form = UserProfileForm()
return render(request, template_name,
{'user_form': user_form, 'profile_form': profile_form, 'data': data},)
else:
return HttpResponseRedirect('/simofa/login')
with that code, data can't passing to the html template.
when i changed render like this
return render(request, template_name,data)
it works properly, but user_form and profile_form isn't passing to the template.
My question:
Can i passing data, user_form, profile_form together to the template?
if can, how? if not, is there any other way ?
I really appreciate your input. so please help me. Thanks ^__^
The render statement isn't expecting a trailing comma like when you're defining a tuple, which is most likely what's causing the error, however your code could use some refactoring....
from django.contrib.auth.decorators import login_required
from django.contrib.auth.models import User
from django.core.urlresolvers import reverse
from django.http import HttpResponseRedirect
# assuming you're using your own form here for some reason...
from .forms import UserForm
# use the login_required decorator instead of manually checking for the session
#login_required
def tambah_user(request, template_name='form_user.html'):
# `users` just makes more sense here for the variable name
users = User.objects.all()
# no need for the extra if clause to create unbound forms
user_form = UserForm(request.POST or None)
profile_form = UserProfileForm(request.POST or None)
if request.method == 'POST':
if user_form.is_valid() and profile_form.is_valid():
user = user_form.save()
# you need to pass in the raw password here,
# otherwise you're hashing the already hashed password
# if you were to be editing an instance
user.set_password(user_form.cleaned_data('password'))
user.save()
profile = profile_form.save(commit=False)
profile.user = user
profile.save()
# you need to use reverse by name to do this
return redirect(reverse('manajemen_user'))
else:
print user_form.errors, profile_form.errors
# notice I have omitted the trailing comma after the context
# dictionary
return render(request, template_name, {'user_form': user_form,
'profile_form': profile_form, 'data': users})
I hope you've read the documentation for authentication in Django, because there are built-in forms and views to do pretty much everything you'd ever need to do for users instead of writing your own.

Django - Form bind data after initialization

I have a user model for which I'm trying to make a view that manages both create/update form rendering/post.
Here is the view that I did for now
def user_edit(request, user_id=None):
obj = {}
status = 200
if user_id:
user = get_object_or_404(User, pk=user_id)
else:
user = User()
user_form = UserForm(instance=user, prefix='user')
if request.method == 'POST':
user_form = UserForm(request.POST, instance=user, prefix='user')
if user_form.is_valid():
user_form.save()
else:
status = 406
obj['user_form'] = user_form
return render(request, 'user/edit.html', obj, status=status)
This works fine, but as you can see, my user_form is initialized 2 times. In order to make this more DRY, at POST time I'd like to update the form definition instead of redefining it. Something like:
if request.method == 'POST':
user_form.data = request.POST
user_form.prefix = 'user'
But I can't make this work. So 2 questions:
Does my view seem valid ?
How can I avoid the form re-definition ?
I would just restructure a couple of lines this way:
def user_edit(request, user_id=None):
status = 200
if user_id:
user = get_object_or_404(User, pk=user_id)
else:
user = User()
user_form = UserForm(request.POST or None, instance=user, prefix='user')
if request.method == 'POST':
if user_form.is_valid():
user_form.save()
else:
status = 406
return render(request, 'user/edit.html', {'form': user_form}, status=status)
Sometimes, it makes sense to duplicate may be 1 line of code to keep it readable.
You should use if condition like this to initialize form only once:
def contact(request):
if request.method == 'POST': # If the form has been submitted...
form = ContactForm(request.POST) # A form bound to the POST data
if form.is_valid(): # All validation rules pass
# Process the data in form.cleaned_data
# ...
return HttpResponseRedirect('/thanks/') # Redirect after POST
else:
form = ContactForm() # An unbound form
return render(request, 'contact.html', {
'form': form,
})
Taken from documentation of django. If you are new to Python, it may seem strange to define a variable in if..else statement, but it is pretty common and valid way in Python.