Factor a small piece of HTML [django] - django

Can I factor a small piece of html code with Django template ?
I have, for example, a lot of images like this:
<img src="/xxxx/xxxx/xxxxxx.jpg">
Can I replace that by {{ image_xxx }} ?

Create a custom template tag:
from django import template
register = template.Library()
#register.simple_tag
def image_by_value(value):
return "/xxxx/xxxx/xxxxxx.jpg"
You can use this in your template as follows:
<img src="{% image_by_value 001 %}">
The value 001 is then passed to the variable value and you can use it to construct the string that contains the image path (i.e., "/xxxx/xxxx/xxxxxx.jpg").

Yes. I suggest creating a custom template tag for it. See the part about inclusion tags.

Related

Django template: How to pass formatted string to include tag

I am new to Django and Django template, I know Django Template is kind of restrictive compare to Rails.
So I am including a template in email like:
{% include "./partials/_info_row.html" with value=f'{request_count} requests' %}
but this throws error: TemplateSyntaxError: Could not parse the remainder: ''{request_count} requests'' from 'f'{request_count} requests''
Is there a way to pass formatted string like this to include tag?
Exception is raised because you can't use f-strings in Django templates - templates language is not actually a Python.
According to doc's there is not need to explicitly pass context variable when using include:
Loads a template and renders it with the current context.
If you need to pass a combined value (context plus something else like "requests" string), you can use simple tag:
tags.py
#register.simple_tag(takes_context=True)
def your_custom_tag(context, format_string):
request_count = context['request_count']
return f'{request_count} requests'
templates
{% with r_count=your_custom_tag %}
{% include "./partials/_info_row.html" with value=r_count %}
{% include "./partials/_info_row.html" with value=request_count|stringformat:'s'|add:' requests' %}
request_count|stringformat:'s' - convert number to string
some_var|add:'requests' - concat strings
Thanks #Chamel and #crazyzuber. I used combination of your answers. Created custom filter.
I knew about custom tag. But I wanted to avoid that because this was not generic tag, it will get used only at one place, so I wanted a solution for which I dont have to write custom tag. But custom tags solution works because it allows you to format string in anyway, which was not possible using existing built-in.
Btw I used #register.filter
#register.filter(is_safe=True)
def request_count_text(count):
return f"{count} request{ 's' if count > 1 else '' }"
and using it as:
{% include "./_info_row.html" with value=request_count|request_count_text %}
This solves my issue.

How to pass a template tag from one template to another in django 2

I am new to Django, and template tags and HTML and have a template where I use a for loop to fill out bootstrap cards from a database. In the model I has a field Resume_link that has a PDF file. All I want to is have the PDF file displayed in a different template file and not in the card where it is too small to read. (Since I am in the loop when someone clicks the link, I just want the specific resume connected to that card to be shown in the new template.) So all I think I should need to do is somehow either pass the the index of the loop, or another variable that identifies the correct database entry. But I think I am missing something fundamental and don't understand how to pass the value of a template tag in one template another template. Is there some way to pass a variable along with the url to a view so the variable can be used to make a new template tag in the desired template?
{% for key in myres %}
...fill out other parts of cards and create the below link...
<a href="{% url "show_pdf" %}" style="font-size: 20px">
{% endfor %}
where show_pdf is the view where I want to show the whole PDF file.
and that template show_pdf is
What I would like to do is be able to pass the key.Resume_link.url, or if not that the pk for that database table to the show_pdf template.
The view for show_pdf is
def show_pdf(request):
template = 'show_pdf.html'
myres=Research.objects.all()
context = {'myres': myres}
return render(request,'mainapp/show_pdf.html', context)
you can pass the current pdf id in the url and access it.
def show_pdf(request, pdf_id):
template = 'show_pdf.html'
myres=Research.objects.get(id=pdf_id)
context = {'myres': myres}
return render(request,'mainapp/show_pdf.html', context)
In you urls.py you must write like this
path('show_pdf/?P<int:pdf_id>/', views.show_pdf, name="show_pdf")
In HTML write <a href="{% url "show_pdf" key.id %}">
Instead of:
<a href="{% url "show_pdf" %}">
... you would include a parameter, e.g.:
<a href="{% url "show_pdf" pdf_id %}">
The resulting URL would now be formatted as indicated by the corresponding urlconf entry, for instance:
http://my.web.site/resumes/show_pdf/1343
(if pdf_id = 1343 ...)
You must specify as many parameters as the corresponding urlconf entry expects, and you may use either positional or keyword syntax (but not both).
Then, when the user clicks on the link, the View specified in that urlconf will get control, and it will have the specified parameter value (1343 ...) as one of its arguments. You'd select the PDF and send it to the template to be properly presented to the user.

Django url template with query parameters

I'm trying to pass query parameters via my view into a link, but it escapes me on how to actually achieve this in a good way.
My template is as following:
<a class="link-button" href="{% url 'videos:index' %}?tag={{ tag }}&page={{ next }}">Next</a>
This returns what I want:
http://127.0.0.1:8000/videos/?tag=1&page=2
While this works, it's quite fragile, does not handle None values and there must be a better way of doing this.
I tried to pass this via the urltemplate tag but it did not seem to be what I was looking for since it requires url config changes for path:
{% url 'videos:index' page=next tag=tag %}
Is there an actual way of doing this or a template tag I can use to get the parameters? I tried searching for this but it gave me a lot of old results and more path urls, like: /videos/page-1/tag-1/ which I'm not looking for.
I was hoping to do something like:
Next
There is no builtin support, but you can add one yourself. You can for example define the following template tag. We can for example construct files in boldface:
app/
templatetags/
__init__.py
urlparams.py
Where in urlparams.py, we define:
from django import template
from urllib.parse import urlencode
register = template.Library()
#register.simple_tag
def urlparams(*_, **kwargs):
safe_args = {k: v for k, v in kwargs.items() if v is not None}
if safe_args:
return '?{}'.format(urlencode(safe_args))
return ''
In the template, we can then load the template tag and then use it like with:
{% load urlparams %}
Next
Note that strictly speaking, the URL parameters can contain the same key multiple times. This is here not possible. So we can not generate all possible URL parameters, but this is usually quite rare, and in my opinion not a good idea in the first place.
you can use default template filter and update your example
<a class="link-button" href="{% url 'videos:index' %}?tag={{ tag|default:'' }}&page={{ next|defaul:'' }}">Next</a>
output for empty tag and page is:
http://127.0.0.1:8000/videos/?tag=&page=
but if you want to dont print None Tag in url you must your own template tag or filter. simply you can write this template filter
#register.filter
def print_query_param(value, key)
if value and key:
return "%s=%s&" % (key, value)
and you can use it as below
<a class="link-button" href="{% url 'videos:index' %}?{{ tag|print_query_param:'tag' }}{{ next|print_query_param:'page' }}">Next</a>
Template tag urlencode
Use the template tag urlencode:
example
Small note:
Note that there is no need to pass the param names themselves through urlencode, since in this case they are literals. If the param names were not literals, you would need to, like this:
example

djangocms-snippet which contains {% %} doesnot show up as placeholder content

I am trying to make my footer a editable from frontend.. using placeholder and inserting footer snippet.
yet, my footer snippet contains django template language
e.g.
Terms and Conditions
as a result, the placeholder content is not showing up, if i remove the django specific things
Terms and Conditions
it is working.
how can I make it work with django reverse url?
I could have given hard coded path but i want the path translatable so i need to reverse by url's name.
If I've got you right, just create custom tag and store templates in database:
from django.template import RequestContext, Template
#register.simple_tag
def footer(request):
snippet = Snippet.object.get(name='footer')
template = Template(snippet.html)
return template.render(RequestContext(request))
{% footer request %}
use this syntax:
{% url 'terms_conditions' as the_url %}
Terms and Conditions
use smartsnippets
These has the capability of rendering django tags

What is the right and efficient way of displaying images based on name in Django

I'm really new to Django. I'm having difficulty displaying images based on their name and according to the url pattern.
So basically the url consists of several variables within them and I want to be able to use that to fetch a particular image that is named with those variables.
Example:
localhost:8080/farm/chicken
this would fetch an image inside of my ../static/images/ folder and get:
farm_chicken.jpg
Another example:
localhost:8080/zoo/alligator
would get:
zoo_alligator.jpg
I can fetch the url parameters. So, should I make these image names within my views.py file and pass the names (zoo_alligator) into a context to be retrieved by the template later on? Would this be the correct way?
Thank you for your advice everybody! I appreciate all the help!
You won't actually do something like that, in general. What you should do is to send the image as a context variable from your view function to your template.
If you are using your url node to determine which picture to show, then in your corresponding view function, you are actually using "alligator" or "chicken" to load up the corresponding Animal class.
Once the correct animal object is instantiated, you could send this animal object to your django template and load in the image using a snippet similar to this:-
Like this:-
{% if animal.get_latest_medium_url %}
<img id="animal_image" class="img-rounded left" src="/media/{{ animal_image }}" />
{% endif %}
The get_latest_medium_url is a method in my Merchant class and it computes the url there.
So, should I make these image names within my views.py file and pass
the names (zoo_alligator) into a context to be retrieved by the
template later on? Would this be the correct way?
Sure, this is one way to do it. Something like this:
(r'show/(?P<in_path>.*)$','someapp.image_view')
Then in image_view:
def image_view(request,in_path):
img = in_path.replace('/','_')+'.jpg'
return render(request,'some_template.html',{'path':img})
However, as your view is very simple - you can pass the path directly to the template from urls.py, using direct_to_template:
from django.views.generic.simple import direct_to_template
(r'show/(?P<in_path>.*)$',direct_to_template,{'template':'some_template.html'})
In some_template.html:
<img src="{{ params.in_path }}">
The problem is that you won't get your string formatting done as the default filters do not have a "replace" function. You can easily write a custom filter:
#register.filter
#stringfilter
def format_path(the_path):
return the_path.replace('/','_')+'.jpg'
Then modify the template:
<img src="{{ params.in_path|format_path }}">
You should read the documentation on writing custom filters and tags for more details including where to store the filter code to make sure django can find it.