Change what's displayed in a Django template using the Python variables - python

I have recently started working on some software that has been written in Python/ Django, and I am looking to change what information is displayed on one of the webpages.
The page currently displays a number of tabs, with different information from the database displayed on each tab. The tabs are titled: Overview, Budget, Works, & Items.
On the Items tab, there are four columns: Items, Initial Sum, Latest Sum, & Notes.
There are views in the Python code that are used to set up what's displayed on each tab, and the one for the Items tab that I want to change is defined with:
def report_ccis(request, project_id):
""" CCI items styled for pdf """
project = Project.objects.get(id=project_id)
budget = get_current_budget(project_id)
cci_total_exc = budget.cci_total_exc_vat_final
cci_grouped_items = budget.cci_items.all().order_by('project_room', 'name')
context = {
'project': project,
'cci_total_exc': cci_total_exc,
'cci_grouped_items': cci_grouped_items,
'webview': 1,
}
try: context['current_budget'] = project.budget_versions.get(current_marker=1) #For option name/date on top of pdfs
except ObjectDoesNotExist: pass
if request.GET.get('stage') == 'pd':
""" Render post deposit homepage """
context['html'] = render_to_string('costing/report2_ccis.html', context)
context['active_tab'] = '4'
return render(request, 'costing/reports_post_deposit.html', context)
else:
""" Render pre deposit homepage """
context['html'] = render_to_string('costing/report_ccis.html', context)
context['active_tab'] = '5'
return render(request, 'costing/reports_pre_deposit.html', context)
I want to remove the 'Latest Sum' column from this tab in the browser, but I'm not sure how to stop the view that's displaying the 'Items' tab from getting/ displaying that information on the tab...
The HTML files that are being populated with by this view have code similar to the following:
{% extends "pdf2_base.html" %}
{% block web_content %}
{% block content_payment_schedule %}
{% endblock content_payment_schedule %}
{% block content_overview %}
{% endblock content_overview %}
{% block content_ccis %}
{{block.super}}
{% endblock content_ccis %}
{% block agreed_variations %}
{% endblock agreed_variations %}
{% block agreed_variations_client %}
{% endblock agreed_variations_client %}
{% block agreed_variations_construction %}
{% endblock agreed_variations_construction %}
{% block unagreed_variations %}
{% endblock unagreed_variations %}
{% endblock web_content %}
As I understand, the HTML used to render the webpages in the browser is generated by the Python variables in the .html file- this is the part that is quite new to me... if it was just plain HTML, I would know how to locate the information that I want to remove from the page, but I can't find where it's being displayed in the HTML files here... or how it's being retrieved by the Python view...
If I 'inspect' the part of the page that I want to remove in the browser, it shows that it is in following structure:
<body>
...
<div class="wrapper">
...
<div class="content">
<div class="tabbed m-r-lg text-sm">
...
<pdf:nexttemplate name="nofooter">
<pdf:nextpage>
...
<pdf:nextpage>
<pdf:nextpage>
<table class="pdf-report left">
<thead>
<tr>
...
<th>Latest Sum (£)</th> == $0
...
</tr>
</thead>
<tbody></tbody>
</table>
...
</pdf:nextpage>
</pdf:nextpage>
</pdf:nexttemplate>
</div>
</div>
</div>
</div>
...
</body>
As is shown by the the HTML, the content that I want to change is displayed in a PDF embedded within the webpage, but obviously, I need to change it via the Python- I'm just not sure how I would do this, as I can't see anything in the Python that references the 'latest sum' field that I want to remove...
Can anyone point me in the right direction?
Edit
The child template for the web page is:
{% extends "costing/reports_tabbed.html" %}
{% load staticfiles utilities %}
{% block title2 %}
| Pre-deposit reports
{% endblock title2 %}
{% block page_title %}
<a id="topbar-shortcuts" data-view-url="{% url 'hub:open_sidebar' %}?app={{app.name}}&p={{project.id}}&po=1">
<span class="m-l-md">Reports</span> <img class="icon open text-sm m-l-md" src="{% static 'img/down-lt.png' %}" >
</a>
<div id="topbar-results" class="{{app.color}}" style="display:none;"></div>
{% endblock page_title %}
{% block tabs %}
{% with 'Overview, budget, works, items'|listify as tabs %}
{% for tab_name in tabs %}
{% with forloop.counter as tab %}
{% if not tab == active_tab|add:0 %}<a class="tab" href="{% url 'costing:report_tabbed' project.id %}?tab={{tab}}">{% else %}<a class="active tab">{% endif %}{{tab_name}}</a>
{% endwith %}
{% endfor %}
{% endwith %}
{% endblock tabs %}
The column I want to remove is displayed on the items tab, but I can't see anything in the view/ HTML that specifies what is displayed on each tab...

Related

Why does the NoReverseMatch error pop up when trying to paginate my django website?

I have a list of data from my models that I would like to paginate as it looks flooded on one singular page and it generally takes a longer time for the page to load. However, when I tried to use a paginating method, it doesn't seem to work in my code.
What I've already done for my code is:
.../clubs/views.py
class ClubListView(generic.ListView):
model = Club
paginate_by = 6
.../clubs/urls.py
from django.urls import path
from . import views
app_name = "clubs"
urlpatterns = [
path('', views.ClubListView.as_view(), name="club-list"),
path('<int:pk>/', views.ClubDetailView.as_view(), name="club-detail"),
]
.../clubs/club_list.html
{% block group_content %}
<hr>
{% comment %} Complete making group display. {% endcomment %}
<p></p>
<div class="col-md-8">
<div class="container">
{% for club in club_list %}
<a class="list-group-item" href="{{ club.get_absolute_url }}">
<h3 class="title list-group-item-heading">{{ club.name }}</h3>
<span>{{ club.slogan|safe }}</span>
</a>
<p></p>
<br>
{% endfor %}
</div>
</div>
{% endblock %}
{% block pagination %}
{% if page_obj.has_previous %}
<a href="{% url 'club-list' page_obj.previous_page_number %}">
Previous Page
</a>
{% endif%}
{% if page_obj.has_next %}
<a href="{% url 'club-list' page_obj.next_page_number %}">
Next Page
</a>
{% endif%}
{% endblock %}
However, it still gives me the error of NoReverseMatch of 'club-list' in my html page even though it is given from the urls.py file. I'm not sure if I don't understand where the issue is coming from.
You are passing the next page number/prev page number as part of the {% url %} function which creates the path, however your URLS.py isn't expecting it as part of the URL path. eg, you don't have a urlpattern for listview/12/.
For a list view, by default next and prev pages numbers gets passed as part of the querystring rather than the path,eg,
/listview?page=12
so your template should look more like (from the docs)
{% block pagination %}
{% if page_obj.has_previous %}
« first
previous
{% endif %}
Page {{ page_obj.number }} of {{ page_obj.paginator.num_pages }}.
{% if page_obj.has_next %}
next
last »
{% endif %}
{% endblock %}

Django Jazzmin add button disappeared after adding mptt admin

I'm using jazzmin for django admin and mptt. After adding mptt to admin, in jazzmin theme add button disappeared.
I'm using latest versions of all libraries
class CustomMPTTModelAdmin(MPTTModelAdmin):
# specify pixel amount for this ModelAdmin only:
mptt_level_indent = 30
admin.site.register(Menu, CustomMPTTModelAdmin)
Here you can see the admin where button disappeared
When I disable jazzmin or remove Mptt add button returns back on place
INSTALLED_APPS = [
# 'jazzmin',
.....
]
Here you can button returns back
There is also issue was opened on github
https://github.com/farridav/django-jazzmin/issues/126
but I could not find solution for this problem
I was facing the exact same issue while using django-mptt and django-jazzmin together. It seems that the admin template admin/mptt-change-list.html currently does not have the {% change_list_object_tools %} tag present, which causes the Add button to not be rendered.
The solution is to override the mptt-change-list.html template with:
{% extends "admin/mptt_change_list.html" %}
{% load admin_list i18n mptt_admin %}
{% block result_list %}
<div class="row">
<div class="col-12 col-sm-8">
{% if action_form and actions_on_top and cl.show_admin_actions %}{% admin_actions %}{% endif %}
</div>
<div class="col-12 col-sm-4">
{% block object-tools %}
{% block object-tools-items %}
{% change_list_object_tools %}
{% endblock %}
{% endblock %}
</div>
<hr>
<div class="col-12">
{% mptt_result_list cl %}
</div>
{% if action_form and actions_on_bottom and cl.show_admin_actions %}
<div class="row">
<div class="col-12">
{% admin_actions %}
</div>
</div>{% endif %}
</div>
{% endblock %}

Frozen-Flask pagination links doesn't load the new page

I am trying to freeze my Flask blog app with Frozen Flask but the problem is I can't get the pagination to work correctly after the freeze().
I'm using the app factory pattern.
Here's my main.routes.py:
#bp.route('/home')
#bp.route('/index')
#bp.route('/')
def index(form=None, methods=['GET', 'POST']):
latest_posts = load_latest_posts(10)
with db_session(autocommit=False):
page = 1
posts = load_all_posts().paginate(page, 10, False)
next_url = url_for('main.index', page=posts.next_num) \
if posts.has_next else None
prev_url = url_for('main.index', page=posts.prev_num) \
if posts.has_prev else None
if current_user.is_anonymous:
return render_template('main/index.html', title='Home', posts = posts,
prev_url=prev_url, next_url=next_url, latest_posts=latest_posts)
load_all_posts() does what is says, returning Post.query.order_by(Post.pub_date.desc())
load_latest_posts(n) is basically the same but fetches the latest (n) posts.
As you see, I'm passing the pagination object to posts which I use in my main/index.html template to render the pagination items:
{% extends 'base.html' %}
{% block posts_preview %}
{% for post in posts.items %}
{% include 'posts/_post.html' %}
{% endfor %}
{% endblock posts_preview %}
{% block footer %}
<ul class="pagination">
{% if prev_url %}
<li>«</li>
{% endif %}
{% for page_num in posts.iter_pages(left_edge=1, right_edge=1, left_current=2, right_current=3) %}
{% if page_num %}
{% if posts.page == page_num %}
<li><a class="active" href="{{url_for('main.index', page=page_num) }}">{{ page_num }}</a></li>
{% else %}
<li>{{ page_num }}</li>
{% endif %}
{% else %}
...
{% endif %}
{% endfor %}
{% if next_url %}
<li>»</li>
{% endif %}
</ul>
{% endblock footer %}
_post.html is nothing fancy, just another template that includes post structure.
If I run this in Flask, it works without a problem. When generating static site with Frozen Flask, page numbers are there but clicking on them wouldn't redirect me anywhere. I see the URL being changed from http://127.0.0.1:5000/ to http://127.0.0.1:5000/?page=2 but the new content doesn't load, only refreshing the current page.
What might be the issue here ? How can I load pages and pagination correctly?
According to the Frozen Flask documentation on how the filenames are generated:
Query strings are removed from URLs to build filenames. For example,
/lorem/?page=ipsum is saved to lorem/index.html. URLs that are only
different by their query strings are considered the same, and they
should return the same response. Otherwise, the behavior is undefined.
This means that, unfortunately, http://127.0.0.1:5000/ and http://127.0.0.1:5000/?page=2 will refer to exactly the same page. To get pagination to work, you'd need to make sure that the page number was part of the URL before the query string - something like http://127.0.0.1:5000/page2/.

Template not rendering properly with if user.is_authenticated for Django

I'm trying to incorporate an template tag/inclusion tag into my sidebar for the site. The main section of the page updates properly when I put:
{% if user.is_authenticated %}
<h1> Hello {{ user.username }}
{% else %}
<h1> Hello </h1>
{% endif %}
When I try to use the same principle in my template tag/sidebar, it seems to ignore user.is_authenticated and will always show 'login' and 'register', when it should be just showing 'logout'.
The body of the html (main index page):
{% load Kappa_extras %}
<body>
<div class="container-fluid">
<div class="row">
<div class="col-sm-2" id="side_section">
{% block sidebar %}
{% get_game_list %}
{% endblock %}
</div>
<!--Main section-->
<div class="col-sm-10" id="main_section">
{% block body %}
{% endblock %}
</div>
</div>
</div>
The get_game_list function from 'Kappa_extras':
from django import template
from Kappa.models import Game, Game_Page
from django.contrib.auth.models import User
register = template.Library()
#register.inclusion_tag('Kappa/sidebar.html')
def get_game_list():
return {'game_list': Game.objects.all()}
and the 'Kappa/sidebar.html':
<div id="side_default_list">
<ul class="nav">
<li>Kappa</li>
{% if user.is_authenticated %}
<li>Log Out</li>
{% else %}
<li>Log In</li>
<li>Register</li>
{% endif %}
</div>
I checked a few older inquires though none of them are working properly. I tried putting request into def get_game_list(request): but it just said did not receive value for the argument. How do I get the sidebar to update properly when user.is_authenticated?
You need to pass the user to your inclusion tag.
#register.inclusion_tag('Kappa/sidebar.html')
def get_game_list(user):
return {'game_list': Game.objects.all(), 'user': user}
Then in your template, call the tag with
{% get_game_list user %}
Alternatively, you can set takes_context=True in your inclusion tag, so that you can access the user from the template context.
#register.inclusion_tag('Kappa/sidebar.html', takes_context=True)
def get_game_list(context):
return {'game_list': Game.objects.all(), 'user': context['user']}
In this case, you don't need to pass the user to the template tag any more.
{% get_game_list %}
See the docs for more information and other examples.

Flask - put contents of a html page into the centre of a template page

I've only just started using Flask. I have a file with a series of links. It's generated by a separate script that returns something along the lines of this
<li>foo1 Name </li>
<li>foo2 Name </li>
<li>foo3 Name </li>
<li>foo4 Name </li>
which I save in a filewithlinks.html file in the templates folder
I want to do something like this
{% extends "template.html" %}
{% block content %}
<h2>The Links</h2>
<ul>
{% extends "filewithlinks.html">
</ul>
{% endblock %}
but when I try that it throws an error. for the {% extends "filewithlinks.html"> %}
Is there a way to do this?
You can only extend one template at a time. For everything else, use macros or include statements.
For your list, using {% include %} is just the ticket:
{% extends "template.html" %}
{% block content %}
<h2>The Links</h2>
<ul>
{% include "filewithlinks.html">
</ul>
{% endblock %}
Use include macro. Replace:
<ul>
{% extends "filewithlinks.html">
</ul>
with:
<ul>
{% include 'filewithlinks.html' %}
</ul>

Categories