Django include template, overwrite 'self' variable? - python

I've been tasked to fix a template structure in a Django app. I am not very familiar with Django as I deal mostly with front end projects built in React.
The Django app is using Wagtail as a backend CMS. I am looping through it's pages, and including a template block and trying to pass variables with the with statement on the include. I can successfully pass variables to the template block, but I need to overwrite the 'self' variable as the template block is looking for self.something.
Here is what my template looks like.
{% load static wagtailimages_tags wagtailcore_tags %}
<div class="c-card {% if self.variant %}c-card--{{ self.variant }}{% endif %}">
{% if self.image %}
{% image self.image original class="c-card__image" loading="lazy" %}
{% endif %}
{% if self.title %}
<h3 class="c-card__title">{{ self.title }}</h3>
{% endif %}
{% if self.text %}
<p class="c-card__content">{{ self.text }}</p>
{% endif %}
{% if self.button.title and self.button.url %}
{% include './button_block.html' with button=self.button %}
{% endif %}
</div>
and then there is the loop and include snippet...
{% for chapter_menu in page.chapters %}
<div class="medium-6 large-4 columns">
{{ chapter_menu.value.title }}
{% include './blocks/card_block.html' with self=chapter_menu.value %}
</div>
{% endfor %}
Doing this self=chapter_menu.value results in a TypeError, which is expected as I am defining self twice. push() got multiple values for argument 'self'
How can I go about doing this? Any docs I can read besides the basic django templating docs? https://docs.djangoproject.com/en/3.0/ref/templates/builtins/#with

add the only attribute to include.... Did not find this in any documentation...
{% include './blocks/card_block.html' with self=chapter_menu.value only %}

Related

Building urls with django template system

So I need to build an url querying multiple objects. I tried to use the template system from django to build it with no success. I was wondering if there is any way of doing this in the template or if I should just write a view function.
{% url 'service-ticket/new' as request %}
{% with request|add:"?" as request %} {% endwith %}
{% for entry in object.items.all %}
{% with request|add:"spareparts="|add_string:entry.item.id|add:"&" as request %}
{% endwith %}
{% endfor %}
<a class="btn-add float-right" href={{ request }} role="button">
THIS SHOW HAVE ALL
</a>

how to use name space instead of hard coded url in django templales for pagination

i am newbie in django,i have django templates where i have added the following code for pagination.here you can see that i have apply hard coded url for pagination.but i don't want to use hard coded url ,i want to use namespace instead of the hard coded url.how can i do this.
Template:
<span class="page-links">
{% if page_obj.has_previous %}
{% if query_string %}
previous
{% else %}
previous
{% endif %}
{% endif %}
</span>
my urls:
url(r'^(?P<chain_pk>[0-9]+)/full/combination/$',
CombinationSearchList.as_view(), name='dash_combination_search_list'),
Update
my django version is 1.6
<span class="page-links">
{% if page_obj.has_previous %}
{% if query_string %}
previous
{% else %}
previous
{% endif %}
{% endif %}
</span>
Please note that I have used point.id on the url to provide the value for the point.id in your hardcoded url. This can be any other variable, like object.pk or object.id or any other context variable. If this is not clear post again with the view code of the page and I can help.

adding form styling to django forms

I am currently in the process of adding a theme to the admin of django one issue I have found it adding styling to the forms is that it is very difficult and I can't find much useful documentation on it. The only real thing I need to do is add classes to the form elements so that they match the theme I am using is this possible and if so how would you go about doing it the code I am currently using is very basic and the basic code included in the standard theme does anybody know how to add classes to these standard bits of code bellow is what I have.
{% if is_popup %}
<input type="hidden" name="_popup" value="1" />
{% endif %}
{% if save_on_top %}
{% block submit_buttons_top %}
{% submit_row %}
{% endblock %}
{% endif %}
{% if errors %}
<p class="errornote">
{% blocktrans count counter=errors|length %}
Please correct the error below.
{% plural %}
Please correct the errors below.
{% endblocktrans %}
</p>
{{ adminform.form.non_field_errors }}
{% endif %}
{% block field_sets %}
{% for fieldset in adminform %}
{% include "admin/includes/fieldset.html" %}
{% endfor %}
{% endblock %}
{% block after_field_sets %}{% endblock %}
{% block inline_field_sets %}
{% for inline_admin_formset in inline_admin_formsets %}
{% include inline_admin_formset.opts.template %}
{% endfor %}
{% endblock %}
{% block after_related_objects %}{% endblock %}
{% block submit_buttons_bottom %}
{% submit_row %}
{% endblock %}
There are a lot of ways to do this, but certainly one way would be to overwrite all the widgets in your ModelAdmin rather than in the template. That could look something like this:
from django.db import models
from django.contrib import admin
from django.forms.extras.widgets import TextInput
class MyModelAdmin(admin.ModelAdmin):
formfield_overrides = {
models.TextField: {'widget': TextInput(attrs={'class':'my-widget-class'},)},
}
You'd have to go through and do that for each widget, but then they'd have the appropriate classes -- at least for that modelAdmin.

Misaka template tags for Django - text wrapped in double quotes

I'd like to replace the standard Markdown implementation in a Django blog I'm building with Github-flavoured Markdown. I'd like to use Misaka, and I've thrown together my own custom template tags. Unfortunately, something has gone awry.
Here is my template tags file, which is in blog/templatetags/gfm.py. The __init__.py file is present in the same folder:
from django import template
from django.template.defaultfilters import stringfilter
import misaka as m
register = template.Library()
#register.filter(is_safe=True)
#stringfilter
def gfm(value):
rendered_text = m.html(value,
extensions=m.EXT_FENCED_CODE,
render_flags=m.HTML_ESCAPE)
return rendered_text
And here is one of my templates:
{% extends 'layout/base.html' %}
{% block header %}
{% endblock %}
{% block content %}
{% load gfm %}
{% if object_list %}
{% for post in object_list %}
<div class="post">
<div class="page-header">
<h1>{{ post.title }}</h1>
</div>
{{ post.text|gfm }}
<p>Posted {{ post.pub_date }}</p>
<p>
{% for category in post.categories.all %}
<a class="badge badge-info" href="/category/{{ category.slug }}/">{{ category.title }}</a>
{% endfor %}
</p>
</div>
{% endfor %}
<br />
<ul class="pager">
{% if page_obj.has_previous %}
<li class="previous">Previous Page</li>
{% endif %}
{% if page_obj.has_next %}
<li class="next">Next Page</li>
{% endif %}
</ul>
{% else %}
<div class="post">
<p>No posts matched</p>
</div>
{% endif %}
{% endblock %}
The outputted text is being returned wrapped in double quotes, which breaks the whole thing. Otherwise, the markup generated seems correct.
Where have I gone wrong here? I know it's not the data in the database as if I use pdb to get the values of value and rendered_text inside the function, they are rendered correctly. For example, here is the plain text version of one post, as printed by pdb:
u'A Python application:\r\n\r\n print "Hello world"'
And here is the version rendered in Markdown using Misaka:
u'<p>A Python application:</p>\n\n<pre><code>print "Hello world"\n</code></pre>\n'
I'm fairly experienced with Django, but I'm new to custom template tags.
Use autoescape tag.
{% autoescape off %}{{ post.text|gfm }}{% endautoescape %}
Alternatively you can use safe filter.
{{ post.text|gfm|safe }}

Python template include a page if condition

i'm developing a small app with Python and Google app engine. I'm using boilerplate (https://github.com/coto/gae-boilerplate) as front-end which follows gae direction and python templates, so nothing diffrent than plain stuff.
Now, what i would like to have is this.
When a user logged in, if the field of name and last name are not filled in i would like to have, in the home page, the profile editing.
The page for editing the profile is a template (which extend the base.html), called edit_profile.html which works well.
The homepage is a template as well (extend the base.html) called home.html.
Now, can i include the edit_profile.html in home.html? how can i do it?
this is what i've, i don't know what to put instead of ???? i tried with
{% block edit_profile.html %} {% endblock %}
but does not work
{% if user_info.name and user_info.last_name %}
..
{% else %}
????
{% endif %}
thanks.
So you want to include only some block of given template. There are two solutions:
1) Create template just for profile editing form and include it into edit_profile.html. Then include it also into home.html to if condition branch:
profile_form.html:
<form action="{% url some-action %}">
{{ form }}
<input type="submit" value="save"/>
</form
profile_edit.html
{% extends "base.html" %}
{% block main %}
{% include "profile_form.html" %}
{% endblock %}
home.html
{% if user_info.name and user_info.last_name %}
{% include "profile_form.html" %}
{% endif %}
2) use variable for extended template:
profile_form.html
{% extend BASE_TEMPLATE %}
and set it into context w/ different value as needed:
in home.html (let's say included_form.html is some basic template)
{% if user_info.name and user_info.last_name %}
{% with "included_form.html" as BASE_TEMPLATE %}
{% include "edit_profile.html" %}
{% endwith %}
{% endif %}
and if you want show form as a standalone page, set BASE_TEMPLATE to base.html

Categories

Resources