Django csrf token missing or incorrect error - django

I have been developing a site using Django and am trying to implement a simple form, based off of one of the models inside my app. I have a few issues with getting it to work, but my current major problem is that I keep receiving the following error: CSRF token missing or incorrect.
I am running Django 1.6 with python 2.7.
I have already looked over the following posts to try fix my problem (and various other solutions to which I give contextual reference to where appropriate), but it has not worked for me:
Django: CSRF token missing or incorrect - Basically, passing RequestContext along with my render_to_response return.
CSRF Token missing or incorrect - I have made sure that django.middleware.csrf.CsrfViewMiddleware appears in my settings.py file and I have tried to add the django.core.context_processors.csrf as instructed to my TEMPLATE_CONTEXT_PROCESSORS setting but there is no change. When I check these settings in the shell, I get the following output:
> from django.conf import settings
> settings.TEMPLATE_CONTEXT_PROCESSORS
('django.contrib.auth.context_processors.auth',
'django.core.context_processors.debug', 'django.core.context_processors.i18n',
'django.core.context_processors.media', 'django.core.context_processors.static',
'django.core.context_processors.tz',
'django.contrib.messages.context_processors.messages')
I placed the following code in my settings.py file but I continue to get the 403 CSRF token error:
import django.conf.global_settings as DEFAULT_SETTINGS
TEMPLATE_CONTEXT_PROCESSORS = DEFAULT_SETTINGS.TEMPLATE_CONTEXT_PROCESSORS + (
'django.core.context_processors.csrf',
)
I have also followed the suggestions given in the error message itself, i.e. makign sure I have the {% csrf_token %} tags in place, using RequestContext instead of Context.
from my views.py file:
from django.shortcuts import render
from django.views.decorators.csrf import csrf_protect, csrf_exempt
from django.template import loader, Context
from django.http import HttpResponse
from forms import StudentForm
from django.http import HttpResponseRedirect
from django.core.context_processors import csrf
from django.template import RequestContext
def edit(request):
form = StudentForm(request.POST or None)
if form.is_valid():
form.save()
return Redirect('/myprofile/')
return render(request, 'myprofile.html',{'form':form})
Please not that I have read several other guides to fixing this problem that involve including RequestContext in several different ways: return render_to_response('myprofile.html', RequestContext(request, {})) and return render_to_response('myprofile.html', RequestContext(request)), none of which worked for me.
my settings.py file:
import django.conf.global_settings as DEFAULT_SETTINGS
INSTALLED_APPS = (
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'myprofile',
)
MIDDLEWARE_CLASSES = (
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
)
TEMPLATE_CONTEXT_PROCESSORS = DEFAULT_SETTINGS.TEMPLATE_CONTEXT_PROCESSORS + (
'django.core.context_processors.csrf',
)
My html code is as follows:
<form action = "/myprofile/" method = "post"> {% csrf_token %}
<ul>
{{ form.as_ul }}
</ul>
<input type = "submit" name = "Submit" value = "Edit Form">
</form>
Please not that I have also attempted to add the token as a hidden input, but this has not solved my issue. The function that generates this view is also the same function that is referred to by the form's action, <form action = "/myprofile/" ...>.
Any assistance with this issue would be greatly appreciated.

Your problem is here:
return render_to_response('myprofile.html',{},RequestContext(request))
Although you have added the csrf:
c = {}
c.update(csrf(request))
You don't do anything with c. To solve this once and for all, just use the render shortcut:
from django.shortcuts import render, redirect
def edit(request):
form = StudentForm(request.POST or None)
if form.is_valid():
form.save()
return redirect('/myprofile/')
return render(request, 'myprofile.html', {'form': form})
Next, in your template, you only use {% csrf_token %} not both it and {{ csrf_token }}. The tag will render the form field.

{{ csrf_token }} seems to be empty and overrides the hidden input field which is generated by {% csrf_token %}. just remove the hidden input field with {{ csrf_token }} from your template and it should work probably.
Also, as you are using RequestContext you don't have to add the CSRF token manually to the template, so you can remove following code from your view.
c = {}
c.update(csrf(request))
See https://docs.djangoproject.com/en/1.6/ref/contrib/csrf/#how-csrf-works for more information.

Related

Django redirect from form upload

From the page
This page isn’t working. If the problem continues, contact the site owner.
HTTP ERROR 405
From the terminal
Method Not Allowed (POST): /
Method Not Allowed: /
[20/Dec/2021 22:00:27] "POST / HTTP/1.1" 405 0
How to redirect to the same page after page upload click.
form.html->included in sidebar.html-> included in home.html
<form method = "POST" action='.' enctype="multipart/form-data">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">Upload</button>
</form>
views.py
from django.shortcuts import render
from .forms import UserProfileForm
def index(request):
print(request.POST)
return render(request,'home.html')
urls.py
from django.conf import settings
from django.urls import path
from django.views.generic.base import TemplateView # new
urlpatterns = [
path('', TemplateView.as_view(template_name='home.html'), name='home'),
]
In your urls.py
Change to:
path(' ', index, name = 'home'),
And you also have to import your view in urls.py
Since you are redirecting to the same page, I assume you are also making a get request when you are serving the form on the webpage.
But when the page is served as a response to a GET request, it is not supposed to contain an empty dictionary in the POST attribute.
Thus, it provides an error.
According to me
def index(request):
if request.method == "POST" :
print(request.POST)
return render(request,'home.html')
Should solve the issue
Acc, to the Django documentation
It’s possible that a request can come in via POST with an empty POST dictionary – if, say, a form is requested via the POST HTTP method but does not include form data. Therefore, you shouldn’t use if request.POST to check for use of the POST method; instead, use if request.method == "POST"
For further reference - https://docs.djangoproject.com/en/3.2/ref/request-response/

Trying to send parameters

I'm trying to obtain dedicated urls of some products that I have in my shop.html page. I have five products that I named "cards": (Ysera, Neltharion, Nozdormu, Alexstrasza, Malygos). Each card should have a dedicated url (localhost:8000/card/1/, localhost:8000/card/2/, etc). but instead of obtaining that url, django launch me that message:
DoesNotExist at /card/1/ card matching query does not exist.
I imported properly the class model "card" in my views.py, in fact I am justly using card in a filter function to obtain all products in shop.html. please look my views.py:
from django.shortcuts import render_to_response
from django.template import RequestContext
from dracoin.apps.synopticup.models import card
from dracoin.apps.home.forms import ContactForm,LoginForm
from django.core.mail import EmailMultiAlternatives
from django.contrib.auth import login,logout,authenticate
from django.http import HttpResponseRedirect
def index(request):
return render_to_response('home/index.html',context_instance=RequestContext(request))
def landing(request):
return render_to_response('home/landing.html',context_instance=RequestContext(request))
def shop(request):
tarj = card.objects.filter(status=True)
ctx = {'tarjetas':tarj}
return render_to_response('home/shop.html',ctx,context_instance=RequestContext(request))
def singleCard(request,id_tarj):
tarj = card.objects.get(id=id_tarj)
ctx = {'card':tarj}
return render_to_response('home/singleCard.html',ctx,context_instance=RequestContext(request))
here my urls.py:
url(r'^card/(?P<id_tarj>.*)/$','dracoin.apps.home.views.singleCard',name='vista_single_card'),
My imported model:
class card(models.Model):
nombre = models.CharField(max_length=100)
descripcion = models.TextField(max_length=300)
status = models.BooleanField(default=True)
def __unicode__(self):
return self.nombre
My singleCard.html:
{% extends 'base.html' %}
{% block title %} Tarjeta {{card.nombre}} {% endblock %}
{% block content %}
<h1>{{ card.nombre }}</h1><br>
<p> {{ card.descripcion }}</p>
{% endblock %}
I don't know if I have a wrong refering "card" class. But I try to apply other answers in this forum. For example:
In Django, how do I objects.get, but return None when nothing is found?
matching query does not exist Error in Django
Django error - matching query does not exist
I don't know if I commit a mistake applying these solutions. Including I try:
tarj = card.objects.filter(id=id_tarj)
Using this I obtain a blank page of my website...
apologizeme in advance my extensive question and if I overlook something.
Thanks!!
Answering to wolendranh I have an urls.py by app and the main urls.py.
Recently I'm learning django by my side and I can't understand how I can define my own consistent identifier in this case.
if it is still useful I put here a traceback generated with the error:
Environment:
Request Method: GET
Request URL: http://localhost:8000/card/1/
Django Version: 1.7
Python Version: 2.7.6
Installed Applications:
('django.contrib.admin',
'django.contrib.admindocs',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'dracoin.apps.synopticup',
'dracoin.apps.home')
Installed Middleware:
('django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware')
Traceback:
File "/home/draicore/project/multilevel/local/lib/python2.7/site-packages/django/core/handlers/base.py" in get_response
111. response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/home/draicore/project/dracoin/dracoin/apps/home/views.py" in singleCard
24. tarj = card.objects.get(id=id_tarj)
File "/home/draicore/project/multilevel/local/lib/python2.7/site-packages/django/db/models/manager.py" in manager_method
92. return getattr(self.get_queryset(), name)(*args, **kwargs)
File "/home/draicore/project/multilevel/local/lib/python2.7/site-packages/django/db/models/query.py" in get
357. self.model._meta.object_name)
Exception Type: DoesNotExist at /card/1/
Exception Value: card matching query does not exist.
excuse me for prolong this question.
As karthikr says in the comment, you don't have a card with id=1.
This is probably because you previously deleted and recreated a card. The id is an autoincrement field, which means the database does not reuse IDs that have been deleted. If you want your item to have a consistent identifier which you can always use to query it in the URL, you should probably define that as an explicit IntegerField (using another name than id), and query against that instead. Even better, use a slug rather than a numeric ID.
I have few things to clarify:
1. Do you have a single urls.py file in your project? or separate for every app.
If you have a separate like "your_project/card/urls" and it is included into main urls.py you should NOT use "card/" in your url. Because Django already knows that request is for that app.
r'^card/(?P<id_tarj>.*)/$' -> r'^(?P<id_tarj>.*)/$'
If it is in main urls.py try to replace:
r'^card/(?P<id_tarj>.*)/$'
to
r'^card/(?P\d+))/$'
P.s.: I don't have anough reputation for comments, so I added an answer. Sorry.

Django Messaging Framework not displaying message despite RequestContext

here's a conundrum for you,
Using Django 1.4, I cannot get messages set through the messages middleware to display in my templates. I have combed through the Django docs and ensured that my settings.py file referenced the relevant apps, context-processors and middleware. I have ensured that my view is rendering with the RequestContext instance. Yet, I still cannot get any of the messages to appear in the template.
settings.py:
MIDDLEWARE_CLASSES = (
'django.middleware.common.CommonMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
)
...
TEMPLATE_CONTEXT_PROCESSORS = (
'django.contrib.auth.context_processors.auth',
'django.core.context_processors.debug',
'django.core.context_processors.i18n',
'django.core.context_processors.request',
'django.core.context_processors.media',
'django.core.context_processors.static',
'django.contrib.messages.context_processors.messages',
'tekextensions.context_processors.admin_media_prefix',
)
...
INSTALLED_APPS = (
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.sites',
'django.contrib.messages',
'django.contrib.staticfiles',
'django.contrib.admin', #Admin interface
'django.contrib.admindocs', #Admin docs
...
My messages error_level is set to 20 (i.e. 'info' and above). I am using the default mappings.
views.py:
from django.contrib import messages
def index(request, *args, **kwargs):
#Do some funky jazz which works like build the timeline & page vars
...
messages.error = (request,"Horsey Bollox!")
messages.add_message = (request, messages.ERROR,"Why won't this f***ing thing work?") #Attempting alternate method
return render_to_response('funkyjazzdirectory/index.html',
{
'page': page,
'timeline': timeline,
},
context_instance=RequestContext(request))
template: (funkyjazzdirectory/index.html)
{% extends "base.html" %}
{% if messages.error %}
<div class="messages-errors">
Error:
<ul>
{% for msg in messages %}
<li>{{msg}}</li>
{% endfor %}
</ul>
</div>
{% endif %}
<p>
Other stuff such as iterating through {{timeline}} which renders absolutely fine
</p>
I have also tried substituting {{msg}} with:
<li>{{msg.message}}</li>
with no success.
The rest of the page outputs fine, Django does not throw an error. The console does not contain anything abnormal. The HTML code produced does not contain the div, nor the list tags anywhere. The template which this one extends (base.html) does not use the {{messages}} variable nor call a template tag which uses it.
I have tried passing the {{messages}} into a custom template tag for testing in the top of the index.html template. Here I can do:
def __init__(self, messages):
self.messages = messages
def render(self, context):
l = dir(context[self.messages])
print(l)
...which produces a list of methods / properties presumably of the message object. Yet, I cannot iterate over this at all, as "for m in messages:" does not run even once. Attempting to discover the size of this entity by:
print(len(context[self.messages]))
gives me nothing in the console.
The only time I've got it to actually output anything was when I manually passed the messages object into the template within the render_to_response tag then iterated over messages.error ({% for msg in messages.error %}) which produced two bullet points in the correct div: the first being filled with what looks like a var dump: ", POST:, COOKIES:{'csrftoken':"... the second bullet point containing just the last error message: "Why won't this f***ing thing work?". (Obviously this was just a test and I have not kept messages in the dict passed via render_to_response as I know it should arrive in the template via the context)
So, where did I go wrong?
Why can I not see my error messages in my template? Why can I not even get the messages to appear in the console?
Any light someone smarter than me can shed would be extremely helpful!
You seem to use a very strange way to add a message:
messages.error = (request,"Horsey Bollox!")
messages.add_message = (request, messages.ERROR,"Why won't this f***ing thing work?")
The correct syntax is:
messages.error(request,"Horsey Bollox!")
messages.add_message(request, messages.ERROR,"Why won't this f***ing thing work?")
The settings and templates are however fine.

Django 1.4 - {{ request.user.username}} doesn't render in template

In my view, I can print request.user.username, however in the template, {{request.user.username}} does not appear. To make this easy, I removed the logic from the function, and I am importing render_to_response & RequestContext.
from django.shortcuts import render_to_response
from django.template import RequestContext
#login_required
#csrf_protect
def form(request):
print request.user.username
data = {}
return render_to_response('form.html', data, context_instance=RequestContext(request))
My guess is that I have problem with my settings.py.
MIDDLEWARE_CLASSES = (
'django.middleware.common.CommonMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
# Uncomment the next line for simple clickjacking protection:
# 'django.middleware.clickjacking.XFrameOptionsMiddleware',
INSTALLED_APPS = (
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.sites',
'django.contrib.messages',
'django.contrib.staticfiles',
'django.contrib.admin',
'django.contrib.admindocs',
'src',
)
Thanks in advance for your help-
As mentioned in the documentation, authenticated user's object is stored within user variable in templates. Mentioned documentation includes the following example:
When rendering a template RequestContext, the currently logged-in user, either a User instance or an AnonymousUser instance, is stored in the template variable {{ user }}:
{% if user.is_authenticated %}
<p>Welcome, {{ user.get_username }}. Thanks for logging in.</p>
{% else %}
<p>Welcome, new user. Please log in.</p>
{% endif %}
EDIT: Thanks to #buffer, who dug out this old answer, I have updated it with most recent state. When it was originally written, in less than a month after Django 1.4 (which was released at the end of March 2012), it was correct. But since Django 1.5, proper method to get username is to call get_username() on user model instance. This has been added due to ability to swap User class (and have custom field as username).
Check out the documentation for RequestContext and TEMPLATE_CONTEXT_PROCESSORS.
If you want request to be in your template context, then you need to include django.core.context_processors.request in your TEMPLATE_CONTEXT_PROCESSORS setting. It is not there by default.
However as Tadeck pointed out in his answer user is already available if you are using the default settings, since django.contrib.auth.context_processors.auth is part of the default list for TEMPLATE_CONTEXT_PROCESSORS.

Django {{ MEDIA_URL }} blank #DEPRECATED

I have banged my head over this for the last few hours.
I can not get {{ MEDIA_URL }} to show up
in settings.py
..
MEDIA_URL = 'http://10.10.0.106/ame/'
..
TEMPLATE_CONTEXT_PROCESSORS = (
"django.contrib.auth.context_processors.auth",
"django.core.context_processors.media",
)
..
in my view i have
from django.shortcuts import render_to_response, get_object_or_404
from ame.Question.models import Question
def latest(request):
Question_latest_ten = Question.objects.all().order_by('pub_date')[:10]
p = get_object_or_404(Question_latest_ten)
return render_to_response('Question/latest.html', {'latest': p})
then i have a base.html and Question/latest.html
{% extends 'base.html' %}
<img class="hl" src="{{ MEDIA_URL }}/images/avatar.jpg" /></a>
but MEDIA_URL shows up blank, i thought this is how its suppose to work but maybe I am wrong.
Update
Latest version fixes these problems.
You need to add the RequestContext in your render_to_response for the context processors to be processed.
In your case:
from django.template.context import RequestContext
context = {'latest': p}
render_to_response('Question/latest.html',
context_instance=RequestContext(request, context))
From the docs:
context_instance
The context instance
to render the template with. By
default, the template will be rendered
with a Context instance (filled with
values from dictionary). If you need
to use context processors, render the
template with a RequestContext
instance instead.
Adding media template context processor also gets the job done
TEMPLATE_CONTEXT_PROCESSORS = (
"django.core.context_processors.request",
"django.contrib.auth.context_processors.auth",
"django.core.context_processors.media",
"django.core.context_processors.static",
)
You can also use direct_to_template:
from django.views.generic.simple import direct_to_template
...
return direct_to_template(request, 'Question/latest.html', {'latest': p})
In addition to question provided above can suggest you to take a look at photologue application. It could help you to avoid direct links in template files and use objects instead.
F.ex.:
<img src="{{ artist.photo.get_face_photo_url }}" alt="{{ artist.photo.title }}"/>
Update: For Django 1.10 users, the both media and static context processors are already moved in django.template from django.core read the following article for more info: https://docs.djangoproject.com/en/1.10/ref/templates/api/#django-template-context-processors-media