Add csrf_token to base.html template - python

In my django project, I'd like to add the csrf_token template tag to the base.html template.
Just dropping the template tag in doesn't get it populated, I'd have to add it to every view, which is not optimal.
So, is there a way to add the csrf_token on every page?
I would think this would be built into whatever view renders the base.html template.

Though I don't know why it's not rendered, it should be inside a form element for it to work properly.
Create a form.html template and reuse it with :
{% include 'form.html' with form=contact_form %}
Place the csrf tag inside form.html

Related

How can I add a form made by formbuilder to every page in Wagtail?

Is there any way to add form (for example feedback form) to every page in CMS? I really like to use Wagtail FormBuilder so Editor guy can change fields.
My first idea is to create custom form page (inherited from AbstractEmailForm) as site root child and load it to base.html trough template tag. I can access page properties this way but I cant render the form.
Here is my template tag:
#register.assignment_tag(takes_context=True)
def get_feedback_form(context):
return context['request'].site.root_page.get_children().type(FeedbackFormPage).first()
And this is how I use it from base.html:
{% get_feedback_form as feedback_form %}
...
{{ feedback_form.specific.title }} <-- this works
{{ feedback_form.specific.form.as_p }} <-- this doesnt work
It would be nice somehow to create a form as snippet or add it to Site Settings, but I didnt find how to do that.
The main issue is how you are generating the form in the template with .form.as_p.
You will need to generate the form with the .get_form function, but you are best to do it within your template as the current user and page needs to be past in as arguments like this.
form = feedback_form_page.get_form(
page=feedback_form_page, user=request.user)
You can see how the form is built for the AbstractForm model here:
https://github.com/wagtail/wagtail/blob/master/wagtail/wagtailforms/models.py#L278
Full detailed example below, along with how you could work the form selection into the Site Settings module.
Link to a Form in Site Settings
Assuming you are referring to the Site Settings contrib module:
http://docs.wagtail.io/en/v1.13/reference/contrib/settings.html
The 'Edit Handlers' section of the documentation explains a great way to link to a page inside of your site settings.
http://docs.wagtail.io/en/v1.13/reference/contrib/settings.html?highlight=site%20settings#edit-handlers
Example (in models.py):
from wagtail.contrib.settings.models import BaseSetting, register_setting
# ...
#register_setting
class MyCustomSettings(BaseSetting):
feedback_form_page = models.ForeignKey(
'wagtailcore.Page', null=True, on_delete=models.SET_NULL)
panels = [
# note the page type declared within the pagechooserpanel
PageChooserPanel('feedback_form_page', ['base.FormPage']),
]
Once you set this model up, you will need to do makemigration and migrate for the changes to work in admin. You will then see inside the settings menu a sub-menu titled 'My Custom Settings'
Adding linked Form to every page
Add a block (so it can be overridden in templates) that has an include in your base template (eg. myapp/templates/base.html).
<!-- Footer -->
<footer>
{% block feedback_form %}{% include "includes/feedback_form.html" %}{% endblock feedback_form %}
{% include "includes/footer.html" %}
</footer>
Create an include template (eg. myapp/templates/includes/feedback_form.html)
{% load feedback_form_tags wagtailcore_tags %}
{% get_feedback_form as feedback_form %}
<form action="{% pageurl feedback_form.page %}" method="POST" role="form">
<h3>{{ feedback_form.page.title}}</h3>
{% csrf_token %}
{{ feedback_form.form.as_p }}
<input type="submit">
</form>
Build a Template Tag to get the form and page
Your template tag needs to build the form with the page's self.get_form() function. Eg. you your template tag (base/templatetags/feedback_form)
from django import template
from myapp.models import MyCustomSettings
register = template.Library()
# https://docs.djangoproject.com/en/1.9/howto/custom-template-tags/
#register.assignment_tag(takes_context=True)
def get_feedback_form(context):
request = context['request']
my_custom_settings = MyCustomSettings.for_site(request.site)
feedback_form_page = my_custom_settings.feedback_form_page.specific
form = feedback_form_page.get_form(
page=feedback_form_page, user=request.user)
return {'page': feedback_form_page, 'form': form}
This still works in wagtail 2.3 just need to replace
#register.assignment_tag(takes_context=True)
with
#register.simple_tag(takes_context=True) to conform with django 2.2
Also {% load feedback_form_tags wagtailcore_tags %} assumes your file inside of templates tags is named feedback_form_tags.py. I also added an __init__.py in the template tags folder although I'm not sure that was actually necessary.

In Django how to render hello.html in base.html?

I am new to django and I misunderstand how to use templates.
I have a a file called base.html which I see as a parent to hello.html.
In hello.html I have this syntax:
{% extends "base.html" %}
{% block hello %}
<h1>hello</h1>
I should see this template. This is the hello.html template.
{% endblock %}
In base.html I have this syntax:
{% block hello %}{% endblock %}
It is my understanding that django should render hello.html inside of base.html
When I deploy my two html files, django ignores my syntax.
Question: How to render hello.html in base.html?
The files are visible inside of github:
https://github.com/danbikle/sof1231/blob/master/hello/templates/base.html
https://github.com/danbikle/sof1231/blob/master/hello/templates/hello.html
Also I deployed them to heroku with these commands:
heroku create sof1231
git push heroku master
You can see base.html deployed to https://sof1231.herokuapp.com
Again,
How to render hello.html in base.html?
To render a template in another template, you use include:
base.html
{% include 'hello.html' %}
Your templates are designed to work with inheritance, and there is nothing wrong with the simplified templates that you show in your question (I didn't check those on github).
I think that your problem might be caused by your view rendering the base.html template, when it should instead be rendering the hello.html template. You should add your view code to your question so that this can be verified. Your view code should be something like this, which renders the child template hello.html:
def hello(request):
template_variables = {'a': 1, 'b': 2}
return render(request, 'hello.html', template_variables)
Another answer (which you have accepted) recommends using include. I don't think that include is the correct approach.
There is a difference between inheriting from a base template and simple inclusion of content from another file. One important benefit of template inheritance is that you can add common content (e.g. menu, side bars, footers, etc.) to a "base" template and then inherit from that base in child templates without duplicating the common content for each page. Another benefit is that the child templates can override content in the base templates, e.g. <title>. This allows you to markup areas of your layout in the base template (using block) and then override the content of the block with other content. This is not possible with a simple include.

How to get mezzanine sidebar to autopopulate for blogposts

I have a blog running mezzanine and I can't get the right side bar to auto populate after a blog post with the information about the blog post, like author, tags, etc. The only way I can get it to show at all it to manually edit the base.html file and add a widget for each field. Isn't there a way to automate this?
Thanks again.
By default, mezzanine includes something similar to what you're asking, the filter_panel.html template. This is the template the blog app uses. In whatever template you're using, include this template in the right_panel block, eg:
{% block right_panel %}
{% include "blog/includes/filter_panel.html" %}
{% endblock %}
If you're just using base.html, you can override the right_panel block by replacing it with just the above includes tag.
Hope that helps!

How to use templates and connect all components in Django?

I'm new to Django and I'm having a somewhat hard time understanding how to connect all of the different pieces together. All of the tutorials I've read on Django templates don't explain how to connect all of the pieces.
I have created my base template called base.html. I have a couple functions inside my views.py class that do specific things. Now I want to create pages that inherit from base.html and display information with respect to each function. So say I want action1.html to call the action_one function and action2.html to call the action_two function. I don't really get how to do this. Any help would be appreciated.
sorry for pasting image but this can help you understand how the flow goes:
there are lots of things going on but i didnot draw them so you can see how the basic flow goes.
for the red part, you can use render_to_response as Thomas says. but i would use render as Kevin does.
here the difference:
render() is the same as a call to render_to_response() with a
context_instance argument that forces the use of a RequestContext.
hope this helps a bit
You're misunderstanding how Django templates and views interact: in Django, views render templates, not the other way around (i.e. templates do not call views).
One example of a view rendering a template is the render_to_response helper function.
As for what defines what view is called when a given URL is accessed, this is your URL configuration.
The following is probably where you want to start here:
In your URL configuration, map the /action_one/ URL to the action_one view.
In your action_one view, render the action_one.html template
Hopefully this code example helps lay it out...
urls.py
url(r'^action1/$', 'yourapp.views.action1'),
url(r'^action2/$', 'yourapp.views.action2'),
views.py
def action1(request):
return render(request, 'action1.html')
def action2(request):
return render(request, 'action2.html')
base.html
<html>
...stuff...
<body>
{% block action %}
{% endblock action %}
</body>
</html>
action1.html
{% extends base.html %}
{% block action %}
... action1 html stuff ...
{% endblock action %}
action2.html
{% extends base.html %}
{% block action %}
... action2 html stuff ...
{% endblock action %}

Creating a "Recent Posts" list in a sidebar.

I'm working on a simple blog app in Django, and i'm having trouble figuring out how to dynamically generate the five most recent posts in a side bar. Each of my views are class based and they extend a generic template, each view maps to one template which I believe is the correct way to do it. I've looked for a way to do this using template tags, but it seems Django doesn't like you to put any logic inside of your templates.
The problem I believe is that I want this to exist within my base.html because I want the recent posts to be displayed site-wide, is a view even supposed to map to your base.html or does that cause problems, i'm pretty new with this. I don't know how to approach this, whether i'm supposed to create a new view for base.html or if I should use my template tags, or if I should extend an existing view(but if I do that it won't be site wide?).
I essentially want the following(they're ordered in reverse chronological order)
{% for post in post_list[:4] %}
{{ post.title }}
{% endfor %}
You can use a template tag. More specifically, an inclusion tag is what you need. This allows you to insert a rendered snippet anywhere inside your template via a small view-like piece of code.
For example, create a templatetags/blog_tags.py file (it's important that you create the templatetags folder within your app; Django searches for them here by default) in your blog app and add the following:
from django import template
register = template.Library()
#register.inclusion_tag('blog/snippets/recent_posts.html')
def render_recent_blogposts():
return {
# This is just an example query, your actual models may vary
'post_list': BlogPost.objects.all().order_by("published_on")[:4]
}
now create a blog/snippets/recent_posts.html template (it can be anywhere as long as it mathecs the #register.inclusion_tag(...) above.):
<ul>
{% for post in post_list %}
<li> {{ post.title }}</li>
...
{% endfor %}
</ul>
finally, in your original template, you can now render your template tags:
<aside>
{% load blog_tags %}
{% render_recent_blogposts %}
</aside>

Categories