How to display the result from SQLite db to html? - python

I am currently learning to build a small web-app. I want to show the list of employees in the web page, and later the ability to add a new employee data to the database. I am using SQlite db and Python Flask.
But I am stuck at this error message: UnboundLocalError: local variable 'rows' referenced before assignment. So my question is, how do I fetch the content of my SQlite db and show them on my webpage? I'd like to show it as a table as well.
Here's my HTML code:
{% extends "layout.html" %}
{% block body %}
<h1> Employees </h1>
<ul>
{% for employee in employees %}
<li> {{ employee }}</li>
{% endfor %}
</ul>
Add a new employee
{% endblock %}
And my python code:
#app.route("/")
def tasks():
rows = db.execute("SELECT * FROM employees")
return render_template("employee_list.html", rows= rows)
Anybody can help me? Thank you.

use macro
{% macro render_comment(emp) %}
<li>{{ emp }}</li>
{% endmacro %}
<ul>
{% for emp in employees %}
{{ render_comment(emp) }}
{% endfor %}
</ul>
and change
return render_template("employee_list.html", rows= rows)
to
return render_template("employee_list.html", employees= rows)

Related

Django plain-text email template generates \n after template tags

Interesting issue here: I have plain-text emails sent by my Django app, with the following code:
email_context = dict()
email_context['to'] = user.display_name
email_context['new'] = user_data['new']
email_context['for_reminder'] = user_data['for_reminder']
plaintext = get_template('email/notification.txt')
text_content = plaintext.render_to_string(email_context)
html = get_template('email/notification.html')
html_content = html.render(email_context)
email = EmailMultiAlternatives(
subject='Assignments',
body=text_content,
to=[user.email],
reply_to=[settings.DEFAULT_FROM_EMAIL],
)
# email.attach_alternative(html_content, "text/html")
email.send()
the 'email/notification_base.txt' template looks like such:
Dear {{ to }},
{% if new %}
You have been assigned to the following NEW cases:
{% block new %}
{% endblock %}
{% endif %}
{% if for_reminder %}
You still have the following previously assigned cases, which need your attention:
{% block for_reminder %}
{% endblock %}
{% endif %}
Thank you for your assistance.
Sincerely,
The Team
the 'email/notification.txt' template just extends base:
{% extends 'email/notification_base.txt' %}
{% load common_tags %}
{% load common_filters %}
{% block new %}
{% for dispute in new %}
Case #: {{ dispute.case_id.no}}
Assignment date: {{ dispute.assignment_date }}
{% endfor %}
{% endblock %}
{% block for_reminder %}
{% for dispute in for_reminder %}
Case #: {{ dispute.case_id.no }}
Assignment date: {{ dispute.assignment_date }}
{% endfor %}
{% endblock %}
My problem with it is, that the email it generates and sends to the addressee, actually gets rendered with a NEWLINE in every spot where the template had {% something %} tags. This results in a very unevenly formatted email text. As an example, if both blocks were missing the email would look like:
Dear Someone,
Thank you for your assistance.
Sincerely,
The Team
Are there any ways around this problem?

Flask app not rendering data from database (psql)

{% extends "layout.html" %}
{% block heading %}
Search Results
{% endblock %}
{% block body %}
fgrgrgtgtg
<ul>
{% for book in books %}
<li>
{{ books.title }}
</li>
{% endfor %}
</ul>
{% endblock %}
#app.route("/search", methods=["GET", "POST"])
def search():
# Query database for book title
books = db.execute("SELECT * FROM books WHERE title = :title",
{"title": request.form.get("title")}).fetchall()
print (books)
return render_template("search.html", books=books)
I'm working on a project for CS50W and I'm stuck. I'm trying to implement a very bare-bones search function that should find all books in my database by title, and then render them on search.html. I just want to get it to work in the simplest way possible before I start adding more complexities to it.
I added "print(books)" in my python code just to make sure that I was successfully pulling the data from the database, and it appears that that is working properly, as it prints the expected results in my terminal. But nothing appears in my html on search.html.
You have a typo; the variable within your loop is book, not books.
{% for book in books %}
<li>
{{ book.title }} # here
</li>
{% endfor %}

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

django template print out by filter id value

I want to print value by id in database,And don't know which keywords to find in Google.
in my views.py, I send transen = TransEn.objects.all() to template
and this will print all datas from database:
{% for words in transen %}
{{words.words|safe }}
{% endfor %}
But I want to print by the value of the id Like:
(Because they are words in English for translating website)
I don't know how to write this in template, please guide me, Thank you very much.
<div><span> TransEn.objects.filter(id='2') </span></div>
<div> TransEn.objects.filter(id='3') </div>
UPDATE:
I have found a method:
I can use if tag, but are there another ideas??
<div>
{% for words in transen %}
{% if words.id == 2 %}
{{ words.words|safe }}
{% endif %}
{% endfor %}
</div>
<div>
{% for words in transen %}
{% if words.id == 3 %}
{{ words.words|safe }}
{% endif %}
{% endfor %}
</div>
If you want to access each item in the QuerySet individually, by index, you should cast it to a list first. You should change your views.py to:
transen = list(TransEn.objects.all())
And then in your template you can access them by index like so:
<div><span> {{ transen.1.words }} </span></div>
<div> {{ transen.2.words }} </div>
A warning from the Django docuemtnation about casting a QuerySet to a list:
Be warned, though, that this could have a large memory overhead, because Django will load each element of the list into memory. In contrast, iterating over a QuerySet will take advantage of your database to load data and instantiate objects only as you need them.

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

Categories

Resources