Page not found after click in Django - python

I have a simple menu-list
{% block menu %}
<ul>
{% for item in list %}
<li>{{ item }}</li>
{% endfor %}
</ul>
{% endblock %}
and a list:
MENU = ['Home','Contact','About']
When I press Contact then go to the address 127.0.0.1:8000/Contact
with this same template but if I again click Contact I'm getting Page not found at 127.0.0.1:8000/Contact/Contact
What can I do about this?

The particular issue here is that the HTML you emit has links to "Contact/", which if you're already at a /Contact URL, will go to a /Contact/Contact like you see here.
The quick fix is to add a / right before the {{item}}, like this:
<li>{{ item }}</li>
However, django has better ways to handle URLs than creating them yourself. Look at the URL dispatcher documentation [1], with the intention of being able to use the url template tag [2].
What that line would end up looking like then is something like this:
<li>{{ item }}</li>
[1] http://docs.djangoproject.com/en/dev/topics/http/urls/
[2] http://docs.djangoproject.com/en/1.2/ref/templates/builtins/#url

Try changing href="{{item}}" to href="/{{item}}":
(% block menu %}
<ul>
{% for item in list %}
<li>{{ item }}</li>
{% endfor %}
</ul>
{% endblock %}
You were using a relative URL which won't work if you're in a different level of the URL path.

Use absolute paths, for example:
MENU = [{'text':'Home',
'url':'/home'},
{'text':'Contact',
'url':'/contact'},
{'text':'Home',
'url':'/home'}]
And code like this:
{% block menu %}
<ul>
{% for item in list %}
<li>{{ text }}</li>
{% endfor %}
</ul>
{% endblock %}
But better solution would be to use some ready CMS app, for example from here django resources page like django-cms ( django-cms.org ).

Related

how to use a django variable in an <a> tag's href?

I want to create a list of entries in which each entry is linked to its page like this: wiki/entry-title. I'm using a for loop to add <li>s to HTML. here's the code:
<ul>
{% for entry in entries %}
<li>{{ entry }}</li>
{% endfor %}
</ul>
urlpattern:
path('wiki/<str:title>', views.entry, name='entry')
what should I type in href to link the <li> to wiki/entry?
You can set your value in url as
<ul>
{% for entry in entries %}
<li>{{ entry }}</li>
{% endfor %}
</ul>
Its better to use {% url %} [Django-doc] template tags as
<ul>
{% for entry in entries %}
<li>{{ entry }}</li>
{% endfor %}
</ul>
NOTE : change value with your value accordingly. For e.g. {{entry.value}} or {{entry.title}} or {{entry.id}}
There is a clear example in the django docs
<ul>
{% for yearvar in year_list %}
<li>{{ yearvar }} Archive</li>
{% endfor %}
</ul>
In django, the template parser always handles django code first, then html/javascript. So you would insert a django variable into an anchor tag the same way you'd insert it anywhere in the template and the parser will replace it before it tries to render the html. If it's a django url, you can use the {% %} format as referenced in the previous answer, and if it's a url that's perhaps stored on the object, you can just use {{ }} (like {{ entry.wiki_url }}). You can also use text for some of the url and a variable for part. So if you have a wiki site that has a base url of, for instance, https://mywiki.com you'd write the href like:
<ul>
{% for entry in entries %}
<li>{{ entry.title }}</li>
{% endfor %}
</ul>
I found out that the only solution that was working for me was this format
{{ x }}
x: this is variable that we want to implement inside href attribute
'url_path_name' : this is the name of the url we gave in urls.py , see :
path("wiki/<str:name>" , views.entry, name="url_path_name")
So this defined url should look like this:
wiki/ ?
href="{% url 'url_path_name' x %}"

Django - The page don't load after click

i'm new in Django developing.
I'm following the tutorial about Library on MDN (https://developer.mozilla.org/en-US/docs/Learn/Server-side/Django)
Until i follow the code all work but i'm trying implement author page by myself. Probably is very stupid issue but is one day that i'm turning around like a dog with its tail.
There is 2 page: author_list and author detail.
I set urls.py (in my project) i set view.py and crate my template.
I follow the same step of tutorial for realize book_list and book_detail but when i click on my author the page don't go to the detail of that author and stay in author_list.html.
Here the code urls.py :
path('authors/', views.AuthorListView.as_view(), name='authors'),
path('author/<int:pk>', views.AuthorDetailView.as_view(), name='author-detail'),
Here views.py:
class AuthorListView(generic.ListView):
model = Author
class AuthorDetailView(generic.ListView):
model = Author
Here author_list.html with link get_absolute_url:
{% extends "base_generic.html"%}
{% block content %}
<h1>Author list</h1>
{% if author_list %}
<ul>
{% for aut in author_list %}
<li>{{ aut.first_name }} - {{ aut.last_name }}</li>
{% endfor %}
</ul>
{% else %}
<p>There are no author.</p>
{% endif %}
{% endblock %}
Here author_detail.html:
{% extends "base_generic.html" %}
{% block content %}
<h1>Author</h1>
{% if author %}
<p><strong>Nome: </strong> {{ author }}</p>
<p><strong>Nato il : </strong> {{ author.date_of_birth }}</p>
<p><strong>Morto il : </strong> {{ author.date_of_death }}</p>
{% endif %}
{% endblock %}
Here the screenshot
Author_list.html before click url=catalog/authors/
After click url change but page not
Thank to all for help
I believe you need DetailView instead of ListView for AuthorDetailView.
Looks like a typo to me, you want generic.DetailView (instead of ListView) for the author/<int:pk> path.
I also don't think it's right to extend base_generic for the template for the detail view. But that depends exactly what is in this base template.

Call links list programatically for Pelican site

I have a Pelican blog. I want to call the external links list programmatically, rather than hard code them into the template. For example, the blog post categories are called programmatically, e.g.,
{% for category, articles in categories[0:10] %}
<li>{{ category }}</li>
{% endfor %}
</div>
<div class="l-box pure-u-1-3">
{% for category, articles in categories[11:20] %}
<li>{{ category }}</li>
{% endfor %}
</div>
<div class="l-box pure-u-1-3">
{% for category, articles in categories[21:30] %}
<li>{{ category }}</li>
{% endfor %}
So to be clear, I am looking to change this code to call from a single file which lists some external weblinks.
Assign them to the LINKS variable in your pelicanconf.py e.g.
LINKS = (
('my link 1', 'http://some.link.here'),
('my link 2', 'http://some.other.link.here')
)
and then call them in your template with
{% for name, link in LINKS %}
{{ name }}
{% endfor %}
All variable defined in your pelicanconf.py, as long as they are in all-caps, can be accessed in your templates.
See: http://docs.getpelican.com/en/3.5.0/themes.html#templates-and-variables

Displaying Page Numbers with django-tables2

I'm currently displaying a dataset using django-tables2.
The docs make no mention of this in particular, so I'm guessing this'll take probably some table overriding - but, I'm hopeful someone out there has already accomplished this.
How can I render page numbers using django-tables2 below my table? What I'd like to be able to display is a horizontal list of page numbers that the user can click.
Thanks in advance.
you need to create a custom page rendering template - you don't need to override any classses.
To do that, start by copying the file
PYTHON\Lib\site-packages\django_tables2\templates\django_tables2\table.html
to the templates directory inside your django application and rename it to mytable.html or whatever else you like.
Now, you need to change the pagination block of that file. There are many ways to do what you like, but a simple way is to add the following lines inside the pagination block (you may remove or keep the other things that are there depending on your specific needs):
{% block pagination.allpages %}
{% for p in table.paginator.page_range %}
{{ p }}
{% endfor %}
{% endblock pagination.allpages %}
Finally, to use your template, just pass your custom template name to the render_table command:
{% load render_table from django_tables2 %}
...
{% render_table table "mytable.html" %}
This is very simple and will give you trouble if you have many pages (so you have to use some ifs to check the number of pages through the table.paginator.num_pages variable). Also, you may highlight the current page and disable the link by using the table.page.number variable.
The above are left as an excersise to the reader :)
Improving on #Serafeim answer (or solving the exercise he left): Here is a pagination block which, using only Django template syntax, renders page numbers that:
are enclosed in a <ul> HTML block, whith CSS classes that "play well" with Bootstrap;
if there are more than 8 pages, at most 3 pages below and above current page are shown;
first and last pages are always shown, with ellipsis between them and the start or end of the range (if needed).
{% with current_page=table.page.number page_count=table.paginator.num_pages rows_per_page=table.page.object_list|length total_rows=table.page.paginator.count %}
{% block pagination %}
<ul class="pagination">
{% block pagination.allpages %}
<li class="current">
{% blocktrans %}Page {% endblocktrans %}
</li>
{% for page in table.paginator.page_range %}
{% with range_start=current_page|add:"-3" range_end=current_page|add:"3" page_count_minus_5=page_count|add:"-5" page_count_minus_1=page_count|add:"-1" %}
{% if page == current_page %}
<li class="active">
<span>{{ page }}</span>
</li>
{% elif page == 1 or page >= range_start and page <= range_end or page == page_count %}
<li class="next">
{{ page }}
</li>
{% endif %}
{% if page == 1 and current_page > 5 or page == page_count_minus_1 and current_page <= page_count_minus_5 %}
<li class="current">...</li>
{% endif %}
{% endwith %}
{% endfor %}
{% endblock pagination.allpages %}
{% block pagination.cardinality %}
<li class="cardinality">
{% if total_rows != rows_per_page %}{% blocktrans %}
{{ rows_per_page }} of {{ total_rows }}{% endblocktrans %}
{% else %}
{{ total_rows }}
{% endif %}
{% if total_rows == 1 %}
{{ table.data.verbose_name }}
{% else %}
{{ table.data.verbose_name_plural }}
{% endif %}
</li>
{% endblock pagination.cardinality %}
</ul>
{% endblock pagination %}
{% endwith %}
Pagination is introduced in version# >= 2.0.0
https://django-tables2.readthedocs.io/en/latest/pages/CHANGELOG.html
Simply add following code in settings.py. Pagination with number will be rendered with bootstap 4 style. Make sure you have bootstrap 4 reference in html template.
DJANGO_TABLES2_TEMPLATE = 'django_tables2/bootstrap4.html'
And check out more styles in documentation.
https://django-tables2.readthedocs.io/en/latest/pages/custom-rendering.html#available-templates

include a template inside another but with extend

Here is what i want
tmpl1.jinja
{% for x in List %}
{% set User = List[x] %}
{% include 'tmpl2.jinja' %}
{% endfor %}
tmpl2.jinja
{% extends "tmpl3.jinja" %}
{% block link %}
<a>share</a>
{% endblock link %}
tmpl3.jinja
User.name
{% block link %}
{% endblock link %}
Basically i have a user block that exists across site with only the action(one or more link but with quiet a few html like image etc) changing. What can i do.
Thanks
For the template part everything looks absolutely ok and there should not be problem if what you do is what you showed.
Is Your list is dict() or actually list()?
Because your problem is here:
{% for x in List %}
{% set User = List[x] %}
This syntax will work only if List is dictionary.
In case of list you should write:
{% for x in List %}
{% set User = x %}

Categories

Resources