Django - didn't return an HTTPResponse Object - python

Sorry if my english is bad, but if you need question, i'm here :)
I saw many answers about this subject of HttpResponse object in Django, but i can't resolve it.
Normally the user insert his email address in order to recieve an email for his new password.
def forgottenPwdEmail(request):
if request.method == 'POST':
form = PasswordResetRequestForm(request.POST)
user = User.objects.get(username=request.user.username)
user.confirmed = True
user.save()
sendResetPasswordMail(user, request.META['HTTP_HOST'])
else:
form = PasswordResetRequestForm()
return render(request, 'front/reset_password_form.html', {'form': form})
After these error is displayed : "View" didn't return an HttpResponse object. It returned None instead. I can recieve the mail anyway, so the problem is in this function but i can't resolve it.
If you have some ideas, i am open :)

You are missing a return in your if statement.
def forgottenPwdEmail(request):
if request.method == 'POST':
form = PasswordResetRequestForm(request.POST)
user = User.objects.get(username=request.user.username)
user.confirmed = True
user.save()
return sendResetPasswordMail(user, request.META['HTTP_HOST'])
else:
form = PasswordResetRequestForm()
return render(request, 'front/reset_password_form.html', {'form': form})
I am assuming that the sendResetPasswordMail is also returning a HttpResponse
Hope this helps

It is happening because your view doesn't return a response for a POST request.
You should add something like redirect page when the email is successfully sent, something like this:
def forgottenPwdEmail(request):
if request.method == 'POST':
form = PasswordResetRequestForm(request.POST)
user = User.objects.get(username=request.user.username)
user.confirmed = True
user.save()
sendResetPasswordMail(user, request.META['HTTP_HOST'])
return redirect('/password-reset-email-sent/')
......

Related

Obtaining data from the form with GET data. Django

How can I get data from the form using the GET method?
For example, I have this form:
class LoansSearchForm(forms.Form):
balance = forms.IntegerField(label='', required=False)
In my view display in the form template this way:
def search_results(request):
form = LoansSearchForm(request.GET)
cd = form.cleaned_data
word = cd['balance']
context = {'form': form,
'test': word,}
return render(request, 'search_results.html', context)
But i still a error:
'LoansSearchForm' object has no attribute 'cleaned_data'
When trying to get them this way:
word = form['balance']
I receive a field with completed data. How to get the data from my the form correctly?
Is my form written correctly? Should I use something like that?
(sorry if my question is trivial, but I found very little information about GET forms)
if request.method == 'GET':
form = LoansSearchForm(request.GET)
if form.is_valid():
print('Hello World')
else:
form = LoansSearchForm()
Recommended: run form.is_valid() and then you do form.cleaned_data
def search_results(request):
form = LoansSearchForm(request.GET)
if form.is_valid():
cd = form.cleaned_data
word = cd['balance']
else:
word = None
context = {'form': form,
'test': word,}
return render(request, 'search_results.html', context)
Forms only get a cleaned_data attribute when is_valid() has been called, and you haven't called it anywhere.
more on cleaned data - documentation
def search_results(request):
form = LoansSearchForm(request.GET)
cd = form.cleaned_data # here <------
word = cd['balance']
context = {'form': form,
'test': word,}
return render(request, 'search_results.html', context)
The problem with your code is that forms are not filled on initialization but when you call form.is_valid, if the form is indeed valid, then it populates cleaned_data
You can read more about the related documentation.
I used name=form.data['field_name'], think it answers your answer of obtaining form values on submit.

Why calling method inside views.py after successful submission of forms doesn't clear the form?

Views.py
def form_name_view(request):
form = FormName()
if request.method == "POST":
form = FormName(request.POST)
if form.is_valid():
form.save(commit=True)
return HttpResponseRedirect('/') # return index(request)
else:
print('INVALID FORM INPUTS')
return render(request, 'first_app/form_page.html', {'form': form})
When I use HttpResponseRedirect to get back to my index page, then everything works correct, but the concern is if I use calling index method instead of HttpResponseRedirect then the behavior is a little bit insane:
After reaching index page if I hit refresh then alert appears says:
The page that you're looking for used information that you entered.
Returning to that page might cause any action you took to be
repeated. Do you want to continue?
If i want to get back to the same form page, by calling that same method again like
return form_name_view(request)
The new form is already filled with previous inserted data, with the message on the form
Topic with this Topic name already exists.
The question is what is the reason, calling method results like this?
def form_name_view(request):
if request.method == "POST":
form = FormName(request.POST)
if form.is_valid():
form.save(commit=True)
return HttpResponseRedirect('/') # return index(request)
else:
print('INVALID FORM INPUTS')
else:
form = FormName()
return render(request, 'first_app/form_page.html', {'form': form})
use this

Python Django - Access Response Headers In View

I am working on a web application which works with entities that all have their unique IDs.
I have a submit form for users to create these entities and this form is in several steps (i.e. view 1 redirects to view 2, etc... until the end of the submission process).
The first view will create the ID of the entity after form submission and I then need to use the ID of the instance created in the other views.
I do not want to pass this ID as a URL parameter to the other views as these will be POST and that means that users could easily manipulate these and create records in models for several IDs. I have managed to pass this ID to several views using the session parameters (request.session) but this is not ideal as this is permanent for the session. Current code below:
def view1(request):
if request.method == 'POST':
form = xxx_creation_form(request.POST)
if form.is_valid():
cleaned_form_data = form.cleaned_data
xxx_entry = Model.objects.create(
... object creation ...
)
request.session['xxx_id'] = xxx_entry.id
return HttpResponseRedirect(reverse('form_2'))
else:
form = xxx_creation_form()
return render(request, 'xxx_form.html', {'form': form})
def view2(request):
xxx_id = request.session['property_id']
if xxx_id == 'SET_BACK_BLANK':
return render(request, 'no_xxx_id.html')
if request.method == 'POST':
form = xxx_form2(request.POST)
if form.is_valid():
cleaned_form_data = form.cleaned_data
xxx_entry = Model.objects.create(
id = xxx_id, #use the id created in step 1
... rest of object creation ...
)
request.session['xxx_id'] = 'SET_BACK_BLANK' #to avoid the misuse during other user interactions.
return HttpResponseRedirect(reverse('thanks'))
else:
form = xxx_form2()
return render(request, 'xxx_form2.html', {'form': form})
Ideally, I would like to pass this ID parameter in the headers of the response as this will avoid having the ID as a session parameter. So I have amended the code to the below:
def view1(request):
if request.method == 'POST':
form = xxx_creation_form(request.POST)
if form.is_valid():
cleaned_form_data = form.cleaned_data
xxx_entry = Model.objects.create(
... object creation ...
)
response = HttpResponseRedirect(reverse('form_2'))
response['xxx_id'] = xxx_entry.id
return response
else:
form = xxx_creation_form()
return render(request, 'xxx_form.html', {'form': form})
def view2(request):
xxx_id = HttpResponseRedirect(request).__getitem__('xxx_id')
if request.method == 'POST':
form = xxx_form2(request.POST)
if form.is_valid():
cleaned_form_data = form.cleaned_data
xxx_entry = Model.objects.create(
id = xxx_id, #use the id created in step 1
... rest of object creation ...
)
return HttpResponseRedirect(reverse('thanks'))
else:
form = xxx_form2()
return render(request, 'xxx_form2.html', {'form': form})
However the above does not work and the error message seems to indicate that there is no 'xxx_id' in the response header.
It would be great if anyone could let me know how to access a response's header in a view as it seems that we cannot amend the request's headers.
Thanks.
What you're asking doesn't really make sense. The response is what is sent from Django to the browser, it is not what the browser sends to Django. That's a completely separate request; in the case of a redirect, your response is simply an instruction to the browser to make that request to a new URL.
The correct thing to do is to use the session, as you are doing. If you are worried about the value being persisted, then pop it out of the session when you use it:
xxx_id = request.session.pop('property_id')

Django Url not redirecting correctly on user creation

I have a user sign up and login template set to send information to the same view (detail). They were both working fine before, however now the redirect on user creation is no longer going to the correct URL (http://127.0.0.1:8000/accounts/login/?next=/accounts/21/) the "accounts/login?next=" portion of the URL is being added for some reason and I cannot understand where it came from as it was not there before.
I'm using stronghold which makes every view login_required unless noted otherwise with #public above it.
I have found some posts about LOGIN_URL needs to be set in setting.py or a next key. However this was working fine before so I do not think that is the problem. let me know if you need more code posted and I will put it up.
Thanks,
-the route I want to hit is
url(r'^accounts/(?P<user_id>\d+)/$', views.detail, name='detail')
-my register view is below
#public
def register(request):
if request.method == 'POST':
form = EmailUserCreationForm(request.POST)
if form.is_valid():
new_user = form.save()
playthrough = PlayThrough(user_id=new_user.id)
playthrough.save()
request.session['user_id'] = new_user.id
return HttpResponseRedirect('/accounts/{}/'.format(new_user.id))
else:
form = EmailUserCreationForm()
return render(request, 'dep_server/register.html', {
'form': form,
})
-this is he view that is supposed to render the user info
def detail(request, user_id):
if request.session['user_id'] == int(user_id):
user = EmailUser.objects.get(id=user_id)
module_list = ModuleRef.objects.all()
return render(request, 'dep_server/detail.html', {
'user': user,
'module_list': module_list
})
else:
return HttpResponseRedirect('/accounts/auth/')
I figured out the problem, I was not logging in the user on creation. Which is why the login worked and the sign up did not. below is the code that I added to the register view, which got it to work.
user = authenticate(
email = form.cleaned_data['email'],
password = form.cleaned_data['password2']
)
login(request, user)

django auth not logging in on register

Struggling with my very basic django auth login system. When a new user registers, they are first redirected to /user/user_id as I'd like (the user is also being created fine), but they are then redirected to /login?next=/user/user_id/ which is being done by the #login_decorator over the user view, (the problem stops if I remove the decorator). (nb. Debug toolbar is breaking up the redirect sequence for me to see). However, if I then manually I include Register view below. I can't see why it is not logging in immediately upon registration. The login method seems to be all there:
def register(request):
if request.method == 'POST':
form = UserCreationForm(request.POST)
if form.is_valid():
new_user = form.save()
new_user = authenticate(username = request.POST['username'],
password = request.POST['password1'])
login(request, new_user)
context = RequestContext(request)
context['user_id'] = new_user.id`
url = '/user/%s/' % new_user.id
return HttpResponseRedirect(url)
else:
form = UserCreationForm()
return render_to_response("registration/register.html", {'form': form},
context_instance=RequestContext(request))
Can you help? Thanks.

Categories

Resources