Django 1.6 "CSRF verification failed. Request aborted." - django

This question may seem like a duplicate but none of the solutions on Google/SO are working, so please do not mark as duplicate.
Here is my view code:
#csrf_protect
def login(request):
if request.POST:
render_to_response('list.tpl', context_instance=RequestContext(request))
else:
# Prepare templates
header = get_template("header.tpl")
body = get_template("login.tpl")
footer = get_template("footer.tpl")
html = header.render(Context({"title": "Login", "charset": "UTF-8"}))
html = html + body.render(Context({}))
html = html + footer.render(Context({}))
return HttpResponse(html)
Here is the login template:
<body>
<div class="bodydiv">
<h3>Login</hd>
<form id="login" method="post" action=".">{% csrf_token %}
User: <input type="text" name="user"><br>
Password: <input type="password" name="password">
<input type="submit" name="submit_login" value="Login">
</form>
</div>
</body>
When I submit the POST request from the form I get CSRF cookie not set.:
I've implemented the four bullets and received the same exact error. What am I missing?
Updated view:
#csrf_protect
def login(request):
print("Method: " + request.method)
if request.method == "POST":
print("IN POST!")
return render(request, 'list.tpl', {})
elif request.method == "GET":
print("IN GET!")
# Prepare templates
header = get_template("header.tpl")
body = get_template("login.tpl")
footer = get_template("footer.tpl")
html = header.render(Context({"title": "Login", "charset": "UTF-8"}))
html = html + body.render(Context({}))
html = html + footer.render(Context({}))
return HttpResponse(html)

You are missing the return. The view is a function and expects you to return an HTTPResponse object.
render_to_response('list.tpl', context_instance=RequestContext(request))
should be
return render_to_response('list.tpl', context_instance=RequestContext(request))
Another thing,
if request.POST
should be
if request.method == 'POST'
Moreover, Avoid using render_to_response. Instead, use render. Source
return render(request, 'list.tpl')

I fixed this issue by using RequestContext instead of Context:
def login(request):
if request.method == "POST":
return render(request, 'login.tpl')
elif request.method == "GET":
# Prepare templates
header = get_template("header.tpl")
body = get_template("login.tpl")
footer = get_template("footer.tpl")
html = header.render(RequestContext(request, {"title": "Login", "charset": "UTF-8"}))
html = html + body.render(RequestContext(request, {}))
html = html + footer.render(Context({}))
return HttpResponse(html)

Related

forms.CharField(initial = "")

My task to make pre-populated content of the page, like this:
content
content = "Sample text"
content = forms.CharField(widget=forms.Textarea, initial = content)
I need something like above, can you help me with realising that in code
class EditPageForm(forms.Form):
content = forms.CharField(widget=forms.Textarea)
def editPage(request, title):
content = util.get_entry(title)
if request.method == "POST":
form = EditPageForm(request.POST)
if form.is_valid():
new_content = form.cleaned_data["content"]
util.save_entry(title, new_content)
return HttpResponseRedirect(reverse("encyclopedia:entry", kwargs={'title': title}))
EditPageForm.initial = content
return render(request, "encyclopedia/editpage.html", {
"form": NewSearchForm,
"editPageForm": EditPageForm,
"title": title
})
Html code:
<form action="{% url 'encyclopedia:editpage' title=title%}" method="post">
<div>
<h3>Content:</h3>
{% csrf_token %}
{{ editPageForm }}
</div>
<input type="Submit">
</form>
You can use widget attributes to add placeholder text that you'd like in your form which can be dynamic and less lines to add.
class EditPageForm(forms.Form):
content = forms.CharField(widget=forms.Textarea(attrs={'placeholder': 'THIS IS MY PLACEHOLDER TEXT'}))
Thank everyone for help, the solution was found.
return render(request, "encyclopedia/editpage.html", {
"form": NewSearchForm,
"editPageForm": EditPageForm(initial={'content': content}),
"title": title
})
Now how that looks like,
You can pass an initial=… parameter [Django-doc] to the form with as value a dictionary with initial values:
from django.shortcuts import redirect
def editPage(request, title):
content = util.get_entry(title)
if request.method == 'POST':
editPageForm = EditPageForm(request.POST, initial={'content': content})
if form.is_valid():
new_content = form.cleaned_data['content']
util.save_entry(title, new_content)
return redirect('encyclopedia:entry', title=title)
else:
editPageForm = EditPageForm(, initial={'content': content})
return render(request, 'encyclopedia/editpage.html', {
'form': NewSearchForm,
'editPageForm': editPageForm,
'title': title
})
That being said, it might be better to work with models and a ModelForm [Django-doc] since this can remove a lot of boilerplate code.

How to differentiate an HTTP Request submitted from a HTML form and a HTTP Request submitted from a client in django?

I have a model in django that is as below:
class Student(Model):
nationality = CharField(max_length=200)
I have a form as below:
class StudentForm(ModelForm):
class Meta:
model = Student
fields = ('nationality', )
my template is as below:
<form method="GET" novalidate id="my_form">
{{ student_form.as_p }}
</form>
<button type="submit" form="my_form" name="my_form">Submit</button>
I have a view as below:
def home(request):
if request.POST:
return HttpResponse('This should never happen')
else:
if request.GET.get('nationality'):
student_form = StudentForm(request.GET)
if student_form.is_valid():
return HttpResponse('get from form submission')
else:
student_form = StudentForm()
print('get from client request')
return render(request, my_template, {'student_form': student_form})
The problem with this method is that if sb submits the form without filling the nationality field, the result would be 'get from client request' that is wrong because the validation error should happen because the request is from submitting a form not direct client get request.
What I can do is that I add a hidden field to my form as below:
<form method="GET" novalidate id="my_form">
{{ student_form.as_p }}
<input type="hidden" id="hidden" name="hidden" value="hidden">
</form>
<button type="submit" form="my_form" name="my_form">Submit</button>
and change my view as below:
def home(request):
if request.POST:
return HttpResponse('This should never happen')
else:
if request.GET.get('hidden'):
student_form = StudentForm(request.GET)
if student_form.is_valid():
return HttpResponse('get from form submission')
else:
student_form = StudentForm()
print('get from client request')
return render(request, my_template, {'student_form': student_form})
However, there should be another method to do this. There should be something in HTTP to tell us the request is fresh get request from client or it is from form submission. I am looking for this.
request.GET is a dictionary. request.GET.get('nationality') is falsy if the dictionary doesn't have the key 'nationality' but also if its value is the empty string (?nationality=). So you should just check the presence of the key, that way you know the form was submitted:
if 'nationality' in request.GET:
# initialise form with `request.GET`
else:
# initial unbound form

The view ___ didn't return an HttpResponse object. It returned None instead

I have a scheduling app where patients can register for appointments. When I submit the form for a new appointment, I get the value error.
views.py
def patient_portal(request):
appointments = Appointment.objects.filter(patient=request.user.patient.pid)
data_input = request.GET.get('date')
selected_date = Appointment.objects.filter(date = data_input).values_list('timeslot', flat=True)
available_appointments = [(value, time) for value, time in Appointment.TIMESLOT_LIST if value not in selected_date]
doctor = Patient.objects.get(doctor=request.user.patient.doctor).doctor
print(doctor)
if request.method == 'POST':
form = AppointmentForm(initial={'doctor': doctor,'patient': request.user.patient}, instance=request.user.patient)
if form.is_valid():
form.save()
return redirect('../home/')
else:
form = AppointmentForm(initial={'doctor': doctor,'patient': request.user.patient}, instance=request.user.patient)
return render(request, 'scheduling/patient.html', {"form" : form, "appointments" : appointments, "available_appointments" : available_appointments, "data_input": data_input, "doctor": doctor})
patient.html:
<form method="post" action="" id="timeslot" enctype="multipart/form-data">
{% csrf_token %}
{{ form|crispy }}
<button type="submit" class="btn btn-primary">Submit</button>
</form>
forms.py:
class AppointmentForm(forms.ModelForm):
class Meta:
model = Appointment
fields = ('doctor','patient','date','timeslot')
Your view must always return an HTTP response. At the moment, your code doesn't handle the case when request.method == 'POST', but the form is invalid.
You can fix your code by de-indenting the final return statement, to move it outside of the else block:
def patient_portal(request):
...
if request.method == 'POST':
form = AppointmentForm(initial={'doctor': doctor,'patient': request.user.patient}, instance=request.user.patient)
if form.is_valid():
form.save()
return redirect('../home/')
else:
form = AppointmentForm(initial={'doctor': doctor,'patient': request.user.patient}, instance=request.user.patient)
return render(request, 'scheduling/patient.html', {"form" : form, "appointments" : appointments, "available_appointments" : available_appointments, "data_input": data_input, "doctor": doctor})

how to get different UI elements by the choicefield value?

Here's my code, something is wrong in the test.html if statement. Could you help me to modified the if condition in test.html that I can get different UI element by the choice-field value?
forms.py
class testForm(forms.Form):
runtype = forms.ChoiceField(choices=[(0, 0), (1, 1)])
byname = forms.CharField()
byindex = forms.IntegerField()
views.py
#csrf_exempt
def osys(request):
if request.method == 'POST':
form = testForm(request.POST, request.FILES)
if form.is_valid():
runtype = form.cleaned_data['runtype']
if runtype == 0:
byname = form.cleaned_data['byname']
if runtype == 1:
byindex = form.cleaned_data['byindex']
print byname, byindex, runtype, filename
return HttpResponse('OK')
else:
form = testForm()
return render_to_response('test.html', locals())
test.html
<form method="post" >
{{form.runtype}}
{% if form.runtype ==0 %}
{{form.byname}}
{% if form.runtype ==1 %}
{{form.byindex}}
<input type="submit" value="Start Run" name="btnRun"></input>
</form>
Django templates are rendered server side to plain HTML which is sent to the client which has no knowledge of the template code.
If you need to do things dynamically client side, you'll need to use JavaScript.

Django 403 CSRF token missing or incorrect

I've encountered this issue but unfortunately still do not know how to fix it. The form renders perfectly, I enter the info and get a CSRF error. The reason given is token missing or incorrect.
View:
def eventSell(request, id):
c = {}
c.update(csrf(request))
event = SquidEvent.objects.get(pk = id)
listing_form = ListingForm(request.POST)
if request.user.is_authenticated():
if request.method == 'POST':
listing_form = ListingForm(request.POST)
if listing_form.is_valid():
cd = listing_form.cleaned_data
user = request.user
item = Object(price = cd['price'], seller = user)
item.save()
return HttpResponseRedirect(reverse('tixeng:index'), c)
#print listing_form
else:
return render_to_response('tixeng/list.html', {'event' : event, 'form' : listing_form}, c)
else:
return HttpResponseRedirect(reverse('allauth.account.views.login'))
Here is my template:
<form action="{% url 'app:eventSell' event.id %}" method="post">
{% csrf_token %}
{{ form }}
<input type="submit" value="Submit">
</form>
I think I've done everything right, I'm not sure what's causing the CSRF error. Also, in case its relevant I was following along with this as a guide:
http://www.djangobook.com/en/2.0/chapter07.html
This stack here Django "The view didn't return an HttpResponse object." was able to help me sort it out. Once I added context_instance = RequestContext(request) to my render_to_response it worked.
context_instance is deprecated since version 1.8.
You can use:
return render(request, 'admin/match_main.html', RequestContext(request, locals()))