In Django template I used:
<form action="/user" method="post">{% csrf_token %}
{{ form.as_p|safe }}
<input type="submit" value="Submit" />
</form>
But error when I change to jinja2 template engine:
Encountered unknown tag 'csrf_token'
My question: csrf_token protection in jinja2 is required?
If required, how to do this?
Thanks in advance!
It seems Jinja2 works differently:
Use <input type="hidden" name="csrfmiddlewaretoken" value="{{ csrf_token }}">
where in Django templates you use {% csrf_token %}
source : http://exyr.org/2010/Jinja-in-Django/
I know this is an old question, but I wanted to update it with the proper way to support the csrf_token when using the new django.template.backends.jinja2.Jinja2 available in Django 1.8+. Using the django template backend you would have called {% csrf_token %}, but using the Jinja2 backend you will call it using {{ csrf_input }} (you can get just the token value instead of the token input using {{ csrf_token }}).
You can see the details in the django.template.backends.jinja2.Jinja2 source
in django 2.x with jinja2 templates engine you get the value of the token with {{ csrf_token }} and the complete hidden input tag with {{ csrf_input }}
source: https://django.readthedocs.io/en/2.1.x/ref/csrf.html
example:
<form action="..." method="post">
{{ csrf_input }}
...
</form>
I use Coffin.
And have same problem when use:
from coffin.shortcuts import render_to_response
return render_to_response('template_name_here.html', context)
try to use instead:
from coffin.shortcuts import render
return render(request, 'template_name_here.html', context)
You don't need to do anything special anymore. csrf_token is supported in django-jinja and works out of the box.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<title>test</title>
</head>
<body>
<p>This should add a hidden input tag with the token. use it in your forms</p>
{% csrf_token %}
</body>
</html>
I had the same problem, and what I noticed is that the CSRF context processor isn't in the list of the default loaded processors. After adding 'django.core.context_processors.csrf' to the TEMPLATE_CONTEXT_PROCESSORS in setting.py I could use the {% csrf_token %} template tag normally.
Related
I am trying to pass data in HTML tag with a form submit to Django
I currently have a template like this:
{% for item in items %}
<div class="product">
{{ item.item_name }}
<form method="POST">
{% csrf_token %}
<input
type="submit"
value="add to cart"
data-pk="{{item.pk}}"
class="add_product"/>
<form>
</div>
{% endfor %}
I want to pass data-pk with a Django form. How do I do that?
Also I know, I can create a view to handle endpoint to do that, and include pk in the url, is that a better solution?
I am new to Django, and I will be grateful for any input on how to do stuff the right way
Instead of data, use value={{item.pk}} and handle the submit logic in your view.
i'm working on Django project, i searched for a while how login and t found that the easiest way is to "django.contrib.auth". so i added my login view to urls.py :
url(r'^login/$','django.contrib.auth.views.login',{'template_name': 'login.html'}),
and this is my template :
<html>
<head>
<title>Django Bookmarks - User Login</title>
</head>
<h1>User Login</h1>
{% if form.errors %}
<p>Your username and password didn't match.
Please try again.</p>
{% endif %}
<form method="post" action=".">{% csrf_token %}
<p><label for="id_username">Username:</label>
{{ form.username }}</p>
<p><label for="id_password">Password:</label>
{{ form.password }}</p>
<input type="hidden" name="next" value="/" />
<input type="submit" value="login" />
</form>
</body>
</html>
It seems you have added some custom backend in settings.py
Try this on shell:
from django.conf import settings
settings.AUTHENTICATION_BACKENDS
Seems django is trying to import a module named backends which you do not have because of some path mistake you are making.
If EmailAuthBackend is defined in a module named backends.py in an app some_app, you need to add some_app.backends.EmailAuthBackend to AUTHENTICATION_BACKENDS.
In early Django versions, this can be due to some backends.py.
I wanted to create an activation email and I used AUTHENTICATION_BACKENDS = ['authentication.backends.EmailBackend'] in my settings.py then I created a file named backends.py, afterward, I deleted backeds.py (because you won't need that in early Dj versions, at least for email verification) and I forgot to delete the AUTHENTICATION_BACKENDS = ['authentication.backends.EmailBackend'] from my settings.py, and that caused the error.
I'm very new to Django and not super familiar with web programming in general, so it's very likely that there is an easy fix to my problem that I'm just unaware of.
My web app is a photo gallery. People can click on a photo to see an enlarged version with buttons on either side for older or newer pictures. In addition, the photos in the gallery can be sorted by tags, which are passed along as URL parameters.
My problem is that when I click on one of the submit buttons, Django replaces the parameters in my URL with the name of the button, thus destroying my reference to what tag I was using. For example, "127.0.0.1:8000/gallery/view/6/?tag=people" upon clicking next, gets converted to "127.0.0.1:8000/gallery/view/6/?older=Older" when it's trying to process the URL.
Code from my HTML:
<form action="/gallery/view/{{ photo.id }}/?tag={{ tag }}" method="get">
{% if has_newer %}
<input type="submit" name="newer" value="Newer">
{% endif %}
<img src="{{ photo.photofile.url }}">
{% if has_older %}
<input type="submit" name="older" value="Older">
{% endif %}
</form>
In my view.py I pass in the tag plus other information in a render_to_response, but I'm not sure how to/if I can reclaim it while handling the buttons.
render_to_response('item/view.html', {'photo':photo, 'tag':tag, 'related_tags': related_tags, 'related_photos': related_photos, 'has_newer': has_newer, 'has_older': has_older}, context_instance=RequestContext(request))
Here's the view.py code for processing the buttons:
if 'newer' in request.GET:
if has_newer:
return HttpResponseRedirect('/gallery/view/%s/?tag=%s'%(newer[1].id, tag))
else:
return HttpResponseRedirect('/gallery/')
if 'older' in request.GET:
if has_older:
return HttpResponseRedirect('/gallery/view/%s/?tag=%s'%(older[1].id, tag))
else:
return HttpResponseRedirect('/gallery/')
<form action="/gallery/view/{{ photo.id }}/" method="get">
{% if has_newer %}
<input type="submit" name="newer" value="Newer">
{% endif %}
<!--This will append a tag parameter with given value to the querystring -->
<input type="hidden" name="tag" value="{{ tag }}">
<img src="{{ photo.photofile.url }}">
{% if has_older %}
<input type="submit" name="older" value="Older">
{% endif %}
</form>
Note that the query string is removed from action (as it won't be used) and the older and newer parameters will still be sent along.
I am using a widget called floppyforms . https://github.com/brutasse/django-floppyforms
In an app called openmaps , my forms look like this
import floppyforms as forms
class GeoForm(forms.Form):
point = forms.gis.PointField()
I think the widget is irrelevant of the view .
And my template looks like this
{# template.html #}
<html>
<head>
{{ form.media }}
</head>
<body>
<form method="post" action="/some-url/">
{% csrf_token %}
{{ form.as_p }}
<p><input type="submit" value="Submit"></p>
</form>
</body>
</html>
what can be the error ? I am testing the widget here , so I am using the basic code provided by them , which is supposed to work .
I have included django.contrib.staticfiles . My django version is 1.3 .
I written a small comments app.
Part of forms.py:
class TinyCommentForm(CommentSecurityForm):
comment = forms.CharField(widget=TinyMCE(attrs={'cols': 80, 'rows': 30}))
Part of models.py:
class TinyComment(BaseCommentAbstractModel):
comment = tinymce_models.HTMLField()
Part of template which using TinyCommentForm:
{% if user.is_authenticated %}
{% get_comment_form for object as form %}
<form action="{% comment_form_target %}" method="POST">
{{ form.comment }}
{{ form.content_type }}
{{ form.object_pk }}
{{ form.timestamp }}
{{ form.security_hash }}
<input type="submit" name="post" class="submit-post" value="Add" />
</form>
{%endif%}
Here I can adding and saving comments, but only without tinymce editor and that is working fine.
If I add to my comment form in template field: {{form.media}} tinymce editor show up, but if I write something there, my POST form seems to be without content, saying that I need to write something to it.
Giving {{form.media}} to <HEAD> sector does not working even if I render through my view the TinyCommentForm as 'form' to this template.
So i tried to import JS more manually and I add to <HEAD> section(using Django 1.3):
<script type="text/javascript" src="{{STATIC_URL}}js/tiny_mce/tiny_mce.js"></script>
Then I check that the src link and it is correct.
So next I add second line there:
<script type="text/javascript" src="{% url tinymce-js "NAME" %}"></script>
Then I create NAME/tinymce_textareas.js with JS code and add containing this folder to TEMPLATE_DIRS. MY urls including tiny_mce urls. But still without results.
Does somebody could illumine me a little?
Got it working good. Answer:
{% if user.is_authenticated %}
{% get_comment_form for object as form %}
<form action="{% comment_form_target %}" method="POST">
{{ form.media }} <!-- This is needed -->
{{ form.comment }}
{{ form.content_type }}
{{ form.object_pk }}
{{ form.timestamp }}
{{ form.security_hash }}
<input type="submit" name="post" class="submit-post" value="Add" />
</form>
{%endif%}
And any JS in section was needless.
But the devil lives in my forms.py which should looks like this:
class TinyCommentForm(CommentSecurityForm):
comment = forms.CharField(widget=forms.Texarea)
And now everythigng works properly.
Edit: The reason of why my comment form need to using widget=forms.Texarea is, i think, that my texareas.js has mode : "textareas". If I am wrong please correct me.