Django Messaging Framework not displaying message despite RequestContext - django

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.

Related

'render' object has no attribute 'GET'

I'm working on a web application for a uni project using django and postgresql. This is my first time working with django forms and when trying to render any of them for a test run and to figure out the views the render fails with the above error message.
I have worked with Django beforehand but this is my first time working with forms -previously, I'd done object creation and edits through API views. I can't find where my code is wrong, but I've tried rewording it, moving lines around to see if it helps (it hasn't,) and even avoiding inheritance and trying to word it as a straightforward form (hasn't helped either.) I have four different forms but they all provide the same error message, so I'm just gonna show one user model extension that I'm not too confident about for an example, in case there's more wrong than I've realized.
This is the code I've got
class JdTform(UserCreationForm):
telefono = forms.IntegerField()
class Meta(UserCreationForm.Meta):
fields = [
'telefono'
]
labels = {
'telefono': 'teléfono'
}
widgets = {
'telefono': forms.NumberInput()
}
def jdt_form_view(request):
if request.method == 'GET':
form = JdTform()
return render(request, 'personas/formu_jdt.html', {'form': form})
if request.method == 'POST':
form = JdTform(request.POST)
if form.is_valid():
user = form.save()
fono = form.cleaned_data.get('telefono')
jdt = jefeDeTaller(telefono=fono, u=user)
jdt.save()
return redirect('cal_fecha')
<html lang="en">
<head>
<meta charset="utf-8">
<title>Gestor de Trabajo</title>
</head>
<body>
<header>
<h1>My Site</h1>
</header>
<main>
<h2>Sign up</h2>
<form action="/your-name/" method="post">
{% csrf_token %}
{{ form }}
<input type="submit" value="Submit">
</form>
</main>
</body>
</html>
urlpatterns = [
path('calendario/<int:ano>/<int:mes>/', views.calendario_mes, name='cal_fecha'),
path('usuarios/jefedetaller/', views.jdt_form_view, name='formulario_jdt'),
The error message I receive on the debug page is
AttributeError at /usuarios/jefedetaller/
'render' object has no attribute 'get'
with traceback
Request Method: GET
Request URL: http://127.0.0.1:8000/usuarios/jefedetaller/
Django Version: 2.2.1
Python Version: 3.5.1
Installed Applications:
['django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'gestor']
Installed Middleware:
['django.middleware.security.SecurityMiddleware',
'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']
Traceback:
File "C:\Users\Flavio\Envs\3dmente\lib\site-packages\django\core\handlers\exception.py" in inner
34. response = get_response(request)
File "C:\Users\Flavio\Envs\3dmente\lib\site-packages\django\utils\deprecation.py" in __call__
96. response = self.process_response(request, response)
File "C:\Users\Flavio\Envs\3dmente\lib\site-packages\django\middleware\clickjacking.py" in process_response
26. if response.get('X-Frame-Options') is not None:
Exception Type: AttributeError at /usuarios/jefedetaller/
Exception Value: 'render' object has no attribute 'get'
With this specific model, the idea is to create a user object, link it directly with a jdt object, and pass the fono information with this instantiation.
Thank you very much beforehand if you can help!

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 csrf token missing or incorrect error

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.

Django CSRF Cookie Not Setting

I have been trying to set up CSRF protection on my POST forms on my django 1.4.3 site and have been getting the 403 CSRF cookie not set error.
I believe I have followed the doc in detail, followed advice on many forums but all to no avail. I have stripped back the code as much as possible and the cookie just does not set. The csrfmiddlewaretoken is present, so that's not the source of the problem. I'm at my wit's end. No doubt the answer is stupidly simple, I just need a fresh set of eyes to point it out to me...
So here's some code:
#urls.py
...
url(r'^csrf/$', csrf_test, name='csrf_test'),
...
#views.py
...
from django.views.decorators.csrf import csrf_protect
#csrf_protect
def csrf_test(request):
c = {}
c.update(csrf(request))
return render_to_response('csrf.html', c)
...
<!-- csrf.html -->
<html>
<body>
<form action="" method="post">
{% csrf_token %}
<input name="Submit" value="Submit" type="submit"/>
</form>
</body>
</html>
#settings.py
...
MIDDLEWARE_CLASSES = (
'django.middleware.csrf.CsrfViewMiddleware',
'django.middleware.common.CommonMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
#for db transactions. Check middleware order if faulty
'django.middleware.transaction.TransactionMiddleware',
# Uncomment the next line for simple clickjacking protection:
# 'django.middleware.clickjacking.XFrameOptionsMiddleware',
'debug_toolbar.middleware.DebugToolbarMiddleware',
)
...
TEMPLATE_CONTEXT_PROCESSORS = global_settings.TEMPLATE_CONTEXT_PROCESSORS + (
'django.core.context_processors.csrf',
'django.core.context_processors.request',
)
...
I am running the django development server on 127.0.0.1:8000.
I have cookies enabled on my browsers and have confirmed cookies are being set from other websites.
I have checked the csrfmiddlewaretoken is being passed as a POST variable.
I always get the error, this is not intermittent.
I have no problem with POST forms when I have disabled the middleware/used #csrf_exempt.
As I say, I'm at my wit's end. What on earth have I missed?
Thanks
Nathan
EDIT:
It now works, but I have no idea what has changed. For anyone reading this in the future I created a new project and app, it created the cookie straight away. Thinking it must have been a settings issue I changed the order of my MIDDLEWARE_CLASSES entries by moving 'django.middleware.csrf.CsrfViewMiddleware' down below 'django.contrib.sessions.middleware.SessionMiddleware'. I ran the original app and it worked. However to test whether the settings change was responsible I reversed the change. It still worked. Go figure.
I hope this helps someone in the future FWIW.
Nathan
if you're using render_to_response then you should probably use a RequestContext
This will handle the csrf protection for you -
def csrf_test(request):
render_to_response('csrf.html', context_instance=RequestContext(request))
You don't need to include the csrf_protect decorator, since you've got the csrf middleware.
def csrf_test(request):
.....
return render(request, 'csrf.html', { ..... })

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.