Django ImageField Template Injection - django

I have checked multiple sources and I can't find any pattern to how the template tags are referenced for ImageFields. Can someone please explain to me every single little part to the template tag call. For instance, {{emp.emp_image.url}} - the first spot before the period has no reference anywhere I look. Not in views, models. No references ever. The second argument is the Field in the model and then urls is a Django argument. What is the first part?
{% load static %}
<!DOCTYPE html>
<html>
<body>
<h1>Name - {{emp.name}}</h1>
<img src="{{emp.emp_image.url}}" alt="Smiley face" width="250" height="250">
<br />
Go Back!!!
</body>
</html>

{{emp.emp_image.url}} :
[1] emp before the period is the name of the variable you sent to the HTML template or commonly known as Context Dictionary parameter.
[2] emp_image is the name of the attribute in your model
[3] url is the parameter that your image which gives django the location of the image

Related

Django template nested include passing variables

I use django template index.html to render the frontpage. It includes another template to create a link icon. This template url_icon.html includes another template icon.html. When passing the arguments down the way, I face with an error. How to fix it?
index.html
.
.
.
{% include "url_icon.html" with name="return" url="/" %}
.
.
.
url_icon.html
{% include "icon.html" with icon={{ name }} %}
icon.html
<img src="/static/images/{{ name }}.png" />
Causing an error:
Could not parse the remainder: '{{' from '{{'
it looks like there are a few things you can do to improve/fix this. Addressing #1 and #2 should fix your issue. I've also added suggestions for best practices that would probably require refactoring (#3, #4).
It looks like you need to remove the curly-braces from name inside the {% include %} tag. Context variables can be used inside tags without extra syntax.
url_icon.html:
{% include "icon.html" with icon=name %}
icon.html will have access to name since you're not using the only keyword when updating its context, so your code might appear to work at first ({% include %} documentation). However, it looks like your intention is to refer to it as icon.
Use the variable icon in instead of name
icon.html:
<img src="/static/images/{{ icon }}.png" />
Optional suggestion: Use Django's staticfiles system
Try using the {% static %} tag for your icon. This will help make deployment easier, especially if you use a separate CDN from your webserver. There's lots of literature on how to set up staticfiles for Django projects in production, it's a large topic, but you'll be able to approach it more easily if you use the {% static %} tag from the beginning.
Optional suggestion: Django's URL routing system
Your route in index.html is hard-coded to be "/". Django has a powerful URL referencing system to leverage. If you've defined the root URL / using Django too, you can refer to it by name. Docs: {% url %}, and for the back-end, reverse().

How to pass a value to a urlpattern using django templating?

So I have this urlpattern where we could type a number on the address bar and it will render an html template which will display the entered number on the page, I decided to give it a little more functionality by piping an add:1 to a links href so that every time we click on the link it adds up to the previous number and then generate the response by displaying that number on the page, But I can't get it to work using django templating I keep getting page not found 404 error, Can anyone please help me with this? Here's is the url pattern which accepts an integer
urlpatterns = [
path('home/<int:num>',views.index,name='index')
]
Here's the HTML template
<!DOCTYPE html>
<html>
<head>
<title>Dynamic urls</title>
</head>
<body>
<h1>Page no. {{num}}</h1>
Change the page
</body>
</html>
the right way is to combine with statment with add filter before passing the new calculated variable to url as second parameter.
{% with num_=num|add:1 %}
Change the page
{% endwith %}
PS
there should be NO spaces around =
variables should NOT start with _
usual math ops (+) are NOT allowed just filters like add

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.

How to provide canonical URL with Django HttpResponseRedirect?

This question is very similar to one I just asked href: Can I get Google search results to use/display the final redirect url?, but now the question is specific to Django.
My site has webpage urls that use the following format:
www.mysite.com/id/pretty_title
The front page links to these pages, but the href actually contains some parameters:
www.mysite.com/id/?some_ugly_parameters_to_let_me_know_what_search_it_is_from
This then redirects to
www.mysite.com/id/pretty_title
which shows the page.
My issue is that Google's search results show the link to the page as the ugly url instead of the pretty redirected one.
What I have learned is that I need to provide a canonical link. But how can I do this when the ugly url page never really exists, at least not as one that I have written?
What happens server side is that the view of the ugly url does a redirect:
return HttpResponseRedirect(pretty_url)
I think this is the correct built template tag that you're looking for.
{{ request.build_absolute_uri }}
You can just put it as part of the HTML returned from the Django template, in the <head> section.
Do you have a base.html in your Django? You can setup a {% block %} as a placeholder for the canonical URL and then set that value in each individual page that {% extends base.html %}
base.html
<html>
<head>
<link rel="canonical" href="{% block canonical_url %}{% endblock %}">
</head>
...
A lot of these proposed solutions have issues if (1) you want your www subdomain to be the canonical one and (2) there are URL params in the request path.
I would actually propose to hard code it in the base template and append request.path.
<link rel="canonical" href="https://www.example.com{{ request.path }}">
If you do end up wanting to use build_absolute_uri, I would do it as follows in your view (or you could create a template function):
canonical_url = request.build_absolute_uri(request.path)
Calling build_absolute_uri() without an argument will call request.get_full_path() and append that to your domain. If a user finds your site via https://www.example.com/?param=123, your canonical URL will include that param.

Template Contexts not recognized from external file (Django)

So, I've been editing a website and have many JavaScript functions that utilize the Contexts that the views.py file passes to the page. Until now, these functions have been contained in the base.html file and so have been loaded onto every page directly. However, to make things cleaner, I copy and pasted all the functions to an external .js file. Now, rather than use the contexts, the functions consider them to be literal strings.
Example:
$('#title').text('{{ event.name }}');
The above line will actually set the text of the element to say "{{ event.name }}" rather than the name of the event. Any ideas on how to fix this? I really don't want to keep these functions in the base file where they can be seen by anyone who inspects the page source.
It doesn't matter if you put your javascript functions in an external file or in your base.html it would still get exposed to the user. Only a minification of the file would actually help to trick the user from seeing the actual values but with javascript all your code is public.
Why you're having this problem is because when you rendered the javascript inline (in your base.html) you had access to the template context.
This is no longer the case and the Django template engine doesn't interpolate your {{ event.name }} anymore.
The problem you're facing as well is a good one. You should never mix and match javascript with Djangos template language or any template language for that matter and the only way of fixing it is to
a) start pulling the values from the DOM ie. render a proper DOM
b) to start to fetch the values from the server, traditionally using AJAX.
And the smallest example that I can muster at the moment is below:
Your view:
def my_django_view(request):
return HttpResponse(json.dumps({'meaningoflife':42}), mimetype='application/json')
Your HTML
<input type="hidden" id="myMeaning" value="{{ meaningoflife }}" />
Your javascript
var meaning = document.querySelector('#myMeaning').value;
alert(meaning); //should alert 42.
In your view you return some form of render_to_response which takes a template argument and a context argument. What the render_to_response function does is read your template, and replace all {{ placeholders }} with the values passed via the context dictionary.
Templates are essentially a complex version of this
"""
<h1>{{ person.name }}</h1>
<p>{{ person.phone_number }}</p>
""".format(person)
The problem is the templating engine does not know files specified by a scripts src attribute is actually a Django template. To fix this don't use the script src attribute. Instead do something like this.
<!--base.html-->
<h1>Site Title</h1>
<p>Some content</p>
<script>
{% include 'jsfile.js' %}
</script>
Using the include statement should do the trick.