Display database using HTML file - html

My site has an option to add products (giving name and price). I store this data using sqlite3 :
import sqlite3
from main import *
from flask import flash
conn = sqlite3.connect('products.db')
c = conn.cursor()
c.execute(""" CREATE TABLE IF NOT EXISTS products (
name text,
price integer
) """)
c.execute("SELECT * FROM products")
existence = False
for name in c:
if name[0] == request.form["product"]:
existence = True
if existence:
flash('This item already exist !! ',category='error')
else:
flash('Item added successfully',category='success')
c.execute (" INSERT OR IGNORE INTO products VALUES (?,?)",[request.form["product"],request.form["price"]])
c.execute("SELECT * FROM products")
conn.commit()
conn.close()
I want to display all products in my website. How it looks like:
{% extends "base.html" %}
{% block title%} Products {% endblock %}
{% block content %}
<h1></h1>
{% endblock %}
Maybe I could use the Python file to display my data? Maybe I should use another way to store my data?

Firstly, create an app route to your products page.
Replace the 'products.html' in return render_template at the end of the python file with whatever your html page name is.
Assign a variable to where you selected all the product then add a fetchall. Return this as product = products when rendering the products.html.
import sqlite3
from main import *
from flask import Flask, render_template, flash
#app.route('/products')
def products():
conn = sqlite3.connect('products.db')
c = conn.cursor()
c.execute(""" CREATE TABLE IF NOT EXISTS products (
name text,
price integer
) """)
products = c.execute("SELECT * FROM products").fetchall()
existence = False
for name in c:
if name[0] == request.form["product"]:
existence = True
if existence:
flash('This item already exist !! ',category='error')
else:
flash('Item added successfully',category='success')
c.execute (" INSERT OR IGNORE INTO products VALUES (?,?)"[request.form["product"],request.form["price"]])
c.execute("SELECT * FROM products")
conn.commit()
conn.close()
return render_template('products.html', products=products)
To display this in your actual product page, we need to use python 'for loops' built in Jinja. This goes through every product in your database and prints out the price and name.
{% extends "base.html" %}
{% block title%} Products {% endblock %}
{% block content %}
{% for product in products %}
<h1>{{ product.price }}</h1>
<h1>{{ product.name }}</h1>
{% endfor %}
{% endblock %}

Related

how to use {%extends%} from base template in python jinja2 when writing sql

In my python project I have two sql files with a lot of overlap.
I would like to create a base.sql and extend other two sql's from this base.sql.
test_jinja2.py
from jinja2 import FileSystemLoader,Environment
with open('sql/sql1.sql', 'r') as sql_file:
sql = sql_file.read()
# folder where all sqls including base.sql is stored
template_folder=template_folder=os.path.join(
os.path.dirname(__file__), 'sql'
)
template = Environment(loader=FileSystemLoader(template_folder)).from_string(sql)
print(template.render())
base.sql
select * from temp1;
{%block part1%} {% endblock part1 %}
sql1.sql
{% extends 'base.sql' %}
{%block part1%}
select * from temp2;
{% endblock part1 %}

How to create query filter based on for-loop button clicked

I'm creating a sample company web database, mainly with employee records and stuff. On one of the page, I want to display all the employees based on their department.
On my models, the department is a CharField choices. I can display the list of these departments by creating a list comprehension in views.py then forloop buttons on the html page with an href tag to the department's page. Now on this where I'm having difficulties. Clearly each element of the for loop will just get redirected to the same page no matter which button was clicked. I've tried to create a query filter and pass the actual department's name and this will work.
On my views i have this:
from django.shortcuts import render
from .models import Staff
def depts(request):
deptList = Staff.department_list
depts = [x[1] for x in deptList]
return render(request, 'dsvstaff/depts.html',{'depts':depts})
def theStaffs(request):
staffs = Staff.objects.filter(department='?')
return render(request, 'dsvstaff/theStaffs.html',{'staffs':staffs})
Then on my Department list page:
{% block content %}
<div class="container">
{% for dept in depts %}
<a class="btn btn-primary" href="{% url 'theStaffs' %}">{{ dept }}</a>
{% endfor %}
</div>
{% endblock %}
This page is where I'm having difficulties:
{% block content %}
{% for x in staffs %}
{{ x.first_name }} {{ x.last_name }} - {{ x.postion }}
{% endfor %}
{% endblock %}
What I wanted is to pass the name of the department's name in the query filter based on the button clicked.
You need to add an extra parameter to determine the departement:
def staff(request, department):
staffs = Staff.objects.filter(department=department)
return render(request, 'dsvstaff/theStaffs.html',{'staffs':staffs})
You will need to add this to the urls.py as well:
# app/urls.py
from django.urls import path
from app.views import staff
urlpatterns = [
path('staff/<department>', staff, 'staff'),
# ...
]
{% block content %}
<div class="container">
{% for dept in depts %}
<a class="btn btn-primary" href="{% url 'staff' department=dept %}">{{ dept }}</a>
{% endfor %}
</div>
{% endblock %}
It however does not look like a good idea to store the department as a CharField. Since a department is an entity, it makes sense to define a model for this, such that you can refer to it like a ForeignKey. This will reduce the database size, make it easier to maintain the database, and it is easier to change the name of a department. See more on database normalization [wiki].

query prints objects instead of some names in django

Is there a simple way to remove query set objects in my template just to print product name without the objects
what it prints
class SellerAccountMixin(object):
products = []
def get_products(self):
account = self.get_account()
products = Product.objects.filter(seller=account)
self.products = products
return products
class SellerDashboard(SellerAccountMixin,FormMixin, View):
def get(self, request, *args, **kwargs):
context["products"] = self.get_products()
return render(request, "sellers/dashboard.html", context)
template
{% if products %}
<div class='pull-left col-sidebar '>
{{ products }}
</div>
You should iterate over your products, like:
{% if products %}
<div class='pull-left col-sidebar '>
{% for product in products %}{{ product.name }} {% endfor %}
</div>
{% endif %}
.name might be a different field. It should be the one you aim to render.

Setting out a list of variables in Salt and then importing into another file

Is it possible to set out a list of salt variables such as:
{% set foo = '1234' %}
{% set bar = '10.1.1.2' %}
{% set environment = salt['grains.get']('env') %}
and then import them into separate .sls file and use them like so:
foo_value = {{ foo }} # sets foo to '1234'
bar_value = {{ bar }} # sets bar to '10.1.1.2'
etc...
The best fit should be the import feature.
You can store the file with variables as described in question and then import them like:
{% from 'yourfile.jinja' import foo with context %}
{% from 'yourfile.jinja' import bar with context %}
{% from 'yourfile.jinja' import environment with context %}
Or alternatively you can add all of them to an array:
{% set vars = {
'foo': '1234',
'bar': '10.1.1.2',
'environment': salt['grains.get']('env'),
}
%}
And then import it at once:
{% from 'yourfile.jinja' import vars with context %}
Best practices on using variables (and import) are described at Salt Best Practices page.

Get Django User group in HTML

I am trying to get Django user's group in HTML for an if tag. This is what I tried:
{% ifequal user.groups.all.0 'ABC' %}
{% endif %}
But this is not working. What other way is there?
Try this:
{% for group in request.user.groups.all %}
{% if group.name == 'ABC' %}{% endif %}
{% endfor %}
Or
{% if request.user.groups.all.0.name == 'ABC' %}{% endif %}
You have to access the current user object from the request context variable. For this, make sure that django.template.context_processors.request is in your template settings.
request.user.groups.all.0 returns a Group model object, so you have to compare against the name field.
I think you will have to use a little Python here. For example, a custom template tag:
#register.filter(name='has_group')
def has_group(user, group_name):
return user.groups.filter(name=group_name).exists()
And in your template:
{% if request.user|has_group:"ABC" %}
...
{% endif %}
(Source: http://www.abidibo.net/blog/2014/05/22/check-if-user-belongs-group-django-templates/)
But maybe you should actually use permissions here.
https://docs.djangoproject.com/en/1.8/topics/auth/default/#authentication-data-in-templates
Edit: Here is a more complete example of the custom template tag:
settings.py:
INSTALLED_APPS = [
...
'yourapp',
...
]
Filesystem:
yourproject/
manage.py
yourproject/
settings.py
wsgi.py
...
yourapp/
__init__.py
templatetags/
__init__.py
yourapp_extras.py
...
yourapp_extras.py:
from django import template
register = template.Library()
#register.filter(name='has_group')
def has_group(user, group_name):
return user.groups.filter(name=group_name).exists()
Template:
{% load yourapp_extras %}
{% if request.user|has_group:"ABC" %}
...
{% endif %}
To get a more thorough understanding of this, I highly recommend reading Django's excellent documentation.
<h1>{{ user.groups.all.0 }}</h1>
{% if user.groups.all.0.name == 'Team2' %}
<h1>YES</h1>
{% else %}
<h1>NO</h1>
{% endif %}
Here, the user.groups.all.0 gives you the first group assigned to the user.
For eg. if the logged in user has groups assigned to him as- 'Team2', 'Programmer', 'Beginner'.
Then {{user.groups.all.0}} will print Team2.
I've used it to print and check the logged in user's group in html template.
OR
{% if request.user|has_group:"mygroup" %}
<h1>Has group mygroup</h1>
{% endif %}
Also works fine in django v1.11. This will check if the current user has 'mygroup' assigned to it or not.
However you'll need to add
from django import template
from django.contrib.auth.models import Group
register = template.Library()
#register.filter(name='has_group')
def has_group(user, group_name):
group = Group.objects.get(name=group_name)
return True if group in user.groups.all() else False
inside a group_check.py in below file structure
--app
|templates
|templatetags
|-- group_check.py