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

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

Related

How to use a javascript variable inside a Django {% url %} tag?

Im trying to dynamically change the link of a button based on which div a user has currently selected.
I tried to run a quick test with a JS variable in the HTML script tag, but Django isn't reading the variable like a num.
<script type="text/javascript">
const testing = 10
</script>
<a href="{% url 'battlefield:onevsone_trainer_selection' num_trainers=testing %}" class='description__button btn btn__large'>Next ></a>
URL looks like:
path('one-vs-one/trainers/<int:num_trainers>', views.oneVsOne, name='onevsone_trainer_selection')
Not sure exactly why it's not working. When I passed it a string of '10' it worked
Django templates are handled server side by django, which means by the time the client browser has received the HTML, the url function, i.e. {% url 'battlefield:onevsone_trainer_selection' num_trainers=testing %}, will have been processed. Javascript, of course, runs in the browser, and you can't pass a javascript variable to a django function after it has arrived at the client.
If you want to change this clientside (without communicating with the server via ajax or something) you might need to change the href attribute directly. You could do something like:
<a id='changeableUrl' href="{% url 'battlefield:onevsone_trainer_selection' num_trainers=1 %}" class='description__button btn btn__large'>Next ></a>
<script>
//figure out where the URL should be going
const testing = 10
//get the current URL
url = document.getElementById('changeableUrl').getAttribute("href")
///replace the end of the url href with our value
url.replace('/1/', '/'+testing+'/')
///write back to the link attribute
document.getElementById('changeableUrl').setAttribute("href", url)
</script>
What you should understand is that django template engine works server-side, whereas Javascript only does its job on client side.
What happens is that you are asking django to render the following template :
<script type="text/javascript">
const testing = 10
</script>
<a href="one-vs-one/trainers/testing" class='description__button btn btn__large'>Next ></a>
Here, testing is not a javascript variable, it's just plain html content. Moreover, it's not an integer at rendering time, so the regex used internally by django shall not be matched and a rendering error shall be raised.
If you really want to set the url paramater client-side, then I see two solutions :
The first is to build the url manually without using the django url function. :
<a href="" id="to-change" class='description__button btn btn__large'>Next ></a>
<script type="text/javascript">
document.getElementById("to-change").href = "one-vs-one/trainers/" + num_trainer;
</script>
The second solution is the one proposed by SamSparx.
Whatever the solution you choose, you should carefully keep in mind that neither of the two if fully safe. In the first case, you make the code a little bit less maintainable by giving more work if one day you change the url in your urls.py file. In the second one, you expose you to a url that is predefined. If JS is not enabled or if something wrong happens on the browser of your client, it may mean that your link shall be linked to what it should not.

Django ImageField Template Injection

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

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.

Webpy Template Function syntax

I am trying to write a web application using Webpy. My application gets info on outputs that are ether off or on. I would like to use an image to show an "on" button or an "off" button.
The data sent to the Webpy template is a dictionary of outputs (key defines the output) and a value (in String type) the value is either '1' for on or '0' for off.
My first thought was to write a function within my template to return the image file based on the value like this:
template_tester_simple.py:
import web
render = web.template.render('templates/')
urls = ('/', 'index')
template_tester_simple = web.application(urls, globals())
class index:
def GET(self):
return render.test_func(data)
def add_data():
data = {'currSet':'75','currTemp':'60','currMode':'Off',
'Cool':'1', 'Heat':'1', 'RevValve':'1', 'EmHeat':'1','Fan':'1',}
return data
data = add_data()
if __name__=="__main__":
web.internalerror = web.debugerror
template_tester_simple.run()
and My test_func.html template:
$def with (data)
<!DOCTYPE html>
<html>
<head>
<title>Test</title>
</head>
$code:
def getSwitchImg(item):
x=""
if (item=='1'):
x="<img src= '../static/switch_on.png'></img>"
else: "<img src= '../static/switch_off.png'></img>"
return x
<body>
<ul>
<li><strong>Cooling</strong><p>
$getSwitchImg($data['Cool'])
</p></li>
<li><strong>Reversing Valve</strong><p>
$getSwitchImg($data['RevValve'])
</p></li>
</ul>
</body>
This returns a Syntax Error as:
at /
invalid syntax Template traceback: File 'templates/test_func.html', line 23 None (test_func.html, line 23)
I could not figure out the Syntax error. It lists a line that is the closing tag of my unordered list , which does not make any sense since it is past all the python code. So It must be something in WebPy template system that I do not understand. Is the function block not getting "closed" properly?
Out of frustration, I then changed my template to the following, using the same template_tester_simple.py:
$def with (data)
<!DOCTYPE html>
<html>
<head>
<title>Test</title>
</head>
<body>
<ul>
<li><strong>Cooling</strong>
$if data['Cool'] == '1':
<img src="../static/switch_on.png" height="15px" width="40px"></img>
$else:
<img src="../static/switch_off.png" height="15px" width="40px"></img>
</li>
<li><strong>Heating</strong>
$if data['Heat'] == '1':
<img src="../static/switch_on.png" height="15px" width="40px"></img>
$else:
<img src="../static/switch_off.png" height="15px" width="40px"></img>
</li>
</ul>
</body>
This works, but I am not defining the function I wanted to use. I am forced to copy/paste basically the same code over and over. As I develop this project further, I plan to add more switches, therefore more digital outputs. If I could get the first template code to work, it will make expanding my app much easier. Also I want to understand the syntax associated with functions within WebPy templates. I have read the templator tutorial on the Webpy website. I thought that once you used "code:" you went to standard python syntax, then once you come out of the indented block, it should be standard HTML. Could someone please explain this syntax, and therefore my error.
I don't know if it's just the way you copy/paste your code here but I've seen an indention problem here.
def getSwitchImg(item):
x=""
if (item=='1'):
x="<img src= '../static/switch_on.png'></img>"
else: "<img src= '../static/switch_off.png'></img>"
return x
It's supposed to be:
def getSwitchImg(item):
x=""
if (item=='1'):
x="<img src= '../static/switch_on.png'></img>"
else:
x="<img src= '../static/switch_off.png'></img>"
return x

Passing url to django to be used as variable?

So when I'm trying to pass url to django views it cuts it. For example, I have a webpage which shows statistics of downloads for users sorted by download amount. Then I want to get details about some user, for example for "Yousuke Kataoka". I press the link and go to user page. Url should be and is mysite.com/user/Yousuke Kataoka, but in the webpage I see "Details for Yousuke", it kinda cuts the url. So of course I can't get any details, because the username is cut.
Here is part of urls.py:
(r'^user/(?P<username>[*_a-zA-Z0-9./-=]+)', 'dq2.web.usermon.views.user')
And here is user.html template:
<html>
<head>
<title>Detailed information for {{usr}}</title>
<script src="/dq2/media/js/sorttable.js"></script>
</head>
<body>
<p>Detailed information for {{usr}}</p>
<table width="30%">
<tr><td>File Downloads (1HR)</td><td align="right">{{file_events_1h}}</td></tr>
<tr><td>File Downloads (24HR)</td><td align="right">{{file_events}}</td></tr>
<tr><td>File Downloads (7D)</td><td align="right">{{file_events_7d}}</td></tr>
<tr><td>File Downloads (30D)</td><td align="right">{{file_events_30d}}</td></tr>
<tr><td>Operations (1HR)</td><td align="right">{{op_events_1h}}</td></tr>
<tr><td>Operations (24HR)</td><td align="right">{{op_events}}</td></tr>
<tr><td>Operations (7D)</td><td align="right">{{op_events_7d}}</td></tr>
<tr><td>Operations (30D)</td><td align="right">{{op_events_30d}}</td></tr>
</table>
And so on..
What should I do?
Try adding a space in your regex. And are you sure you meant to have /-= in there?