Django how to use array in template within a forloop - html

Im trying to use an array inside an html file within a loop
views
def noticia(request, noticia_id):
noticia = get_object_or_404(Noticia, pk=noticia_id)
user_like = False
likes = []
dislikes = []
x = 0
for comentario in noticia.comentario_set.all().order_by('-pub_data'):
likes.append(0)
dislikes.append(0)
for comentario in noticia.comentario_set.all():
for like in comentario.like_set.all():
if like.like:
likes[x] += 1
elif like.dislike:
dislikes[x] += 1
if like.user == request.user:
user_like = True
return render(request, 'Bola/Noticia.html', {'noticia': noticia, 'user_like': user_like, 'likes': likes,
'dislikes': dislikes})
Html
{% for comentario in noticia.comentario_set.all|dictsortreversed:"pub_data"%}
{% for like in comentario.like_set.all %}
<p>{{ likes.forloopcounter0 }} {{ dislikes.forloopcounter0 }}</p>
Any idea how to make this work?

Probably there is a better way of doing it by using Conditional Aggregation.
To use that, first lets update the ForeignKey relation between Comentario and Like using related_name:
class Like(models.Model):
comment = models.ForeignKey(Comentario, related_name='likes', on_delete=models.CASCADE)
Now use that related name in queryset:
from django.db.models import Count, Case, When, IntegerField
...
comments = noticia.comentario_set.all().annotate(
like_count=Count(Case(
When(likes__like=True, then=1),
output_field=IntegerField(),
)).annotate(dislike_count=Count(Case(
When(likes__like=False, then=1),
output_field=IntegerField(),
))
)
return render(request, 'Bola/Noticia.html', {'comments': comments})
Then use it in template:
{% for comentario in comments %}
{{ comentario.like_count }}
{{ comentario.dislike_count }}
{% endfor %}

Related

Display database using HTML file

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 %}

Loading specific foreign key attribute in Django Template

Devs,
I have a 2 Models and one of them have a foreign key attribute as a reference to the other. Now I am trying to view both objects in my Template.
class ItemDetailView(DetailView):
model = Item
template_name = "product.html"
def get_context_data(self, **kwargs):
context = super(ItemDetailView, self).get_context_data(**kwargs)
context['markets'] = Market.objects.all()
# And so on for more models
return context
In my template I just want the exact market for my product
I tryed something like this:
{% for market in markets %} // or {% for object.market in markets %}
{% if market.market == object.market %}
>> Do smth if conditions match <<
{% endif %}
{% endfor %}
In the loop I get strings like x1, x2, x3 and object.market have the value x1.
So I just want to output the object for the corresponding market.
But if I check {% if market.market == object.market %} the conditions somehow don't match. When I print them out inside the loop I get x1,x2,x3,... for market.market and x1,x1,x1,... for object.market
These are my models:
class Market(models.Model):
market = models.CharField(max_length=30)
branch = models.CharField(choices=BRANCH_CHOICES, max_length=1)
image = models.ImageField(blank=True)
slug = models.SlugField(blank=True)
def __str__(self):
return self.market
def get_absolute_url(self):
return reverse("core:market-product-list", kwargs={
'slug': self.slug
})
class Item(models.Model):
title = models.CharField(max_length=100)
market = models.ForeignKey(Market, related_name='children', on_delete=models.CASCADE, blank=True, null=True)
price = models.FloatField()
discount_price = models.FloatField(blank=True, null=True)
category = models.ForeignKey(ItemCategory, related_name='children', on_delete=models.CASCADE, blank=True, null=True)
label = models.CharField(choices=LABEL_CHOICES, max_length=1)
slug = models.SlugField()
path = models.CharField(default='/market-product-list/', max_length=100)
description = models.TextField()
image = models.ImageField()
I just solved the issue. The problem was that object.market is interpreted as an object not as a string. So it was impossible to check the conditions in the if-clause. I managed to output the corresponding market with converting the object to a string like this:
At first:
{% if object.market|slugify|capfirst == market.market %}
and then changed it to simply
{% if object.market == market %}
which is obviously the better solution
PS: I also learned that this is bad programming I should not filter in a Template but I am new to Django and I am glad that things are working now :)
Just call the field for the particular market as in the model.
{% for market in markets %} // or {% for object.market in markets %}
{% if market.market == object.market %}
{{ market.fieldname }}
{% endif %}
{% endfor %}
Why don't you loop through Product(Item) objects?

Auto complete Flask wtforms

I want to auto-update my total amount field using quantity and item price? is there any way to do it using a flask without javascript? I want the total amount to be updated while typing quantity and item price.
class ItemForm(FlaskForm):
item = StringField('Item')
quantity=IntegerField('Quantity')
item_price=IntegerField('Item Price')
class Meta:
csrf = False
class CostumerForm(FlaskForm):
costumer_name=StringField('Costumer Name: ')
item_detail = FieldList(FormField(ItemForm), min_entries=1)
add_item = SubmitField(label='Add Item')
remove_item = SubmitField(label='Remove Item')
total_amount=IntegerField('Total Amount')
paid_amount=IntegerField('Paid Amount')
submit=SubmitField('Submit')
proceed=SubmitField('Proceed')
#app.route('/costumer',methods=['GET','POST'])
#login_required
def costumer():
form=CostumerForm()
if form.add_item.data:
form.item_detail.append_entry()
return render_template('costumer.html', form=form)
if form.remove_item.data:
form.item_detail.pop_entry()
return render_template('costumer.html', form=form)
if form.validate_on_submit():
item=breakdown(form.item_detail.data)[0]
quantity=breakdown(form.item_detail.data)[1]
item_price=breakdown(form.item_detail.data)[2]
amount=breakdown(form.item_detail.data)[3]
total_amount=breakdown(form.item_detail.data)[4]
remaning_amount=total_amount-form.paid_amount.data
sales=Costumer(admin_id=current_user.id,item_id=item,
costumer_name=form.costumer_name.data,quantity=quantity,
item_price=item_price,amount=amount,total_amount=total_amount,
paid_amount=form.paid_amount.data,remaning_amount=remaning_amount)
db.session.add(sales)
db.session.commit()
return redirect(url_for('salesvoucher'))
return render_template('costumer.html',form=form)
costumer.html
Sales
{{form.hidden_tag()}}
{{form.costumer_name.label}}{{form.costumer_name(class='form-control input-group-ig',placeholder='Costumer Name')}}
Item
Quantity
Item Price
{% for field in form.item_detail %}
{% for f in field%}
{{ f(class='form-control') }}
{% endfor %}
{% endfor %}
{{ form.add_item(class='btn btn-primary') }} {{ form.remove_item(class='btn btn-danger') }}
{{form.proceed(class='btn btn-primary')}}
```
no way. even when you're updating in only on the frontend, you must use javascript.

'Profile' object is not iterable

views.py.
#login_required
def friends_profile(request):
f_profiles = Profile.objects.get(user=request.user)
return render(request, 'mains/friends_profile.html', {'f_profiles':f_profiles} )
urls.py
path('friends_profile/', views.friends_profile, name='friends_profile'),
template = friends_profile.html
{% extends "mains/base.html" %}
{% block content %}
{% for friends in f_profiles %}
{{ friends.full_name }}
{% empty %}
<li>NO DATA</li>
{% endfor %}
{% endblock content %}
models.py
class Profile(models.Model):
user = models.OneToOneField(User,
on_delete=models.CASCADE,default='',unique=True)
full_name = models.CharField(max_length=100,default='')
friends = models.ManyToManyField(User, related_name='friends',blank=True)
email = models.EmailField(max_length=60,default='')
date_added = models.DateTimeField(auto_now_add=True)
def get_friends(self):
return self.friends.all()
def get_friends_no(self):
return self.friends.all().count()
def __str__(self):
return f'{self.user.username}'
STATUS_CHOICES = (
('send', 'send'),
('accepted','accepted'),
)
class Relationship(models.Model):
sender = models.ForeignKey(Profile, on_delete=models.CASCADE,
related_name='sender')
receiver = models.ForeignKey(Profile, on_delete=models.CASCADE,
related_name='receiver')
status = models.CharField(max_length=8, choices=STATUS_CHOICES)
def __str__(self):
return f"{self.sender}-{self.receiver}-{self.status}"
'Profile' object is not iterable. This is raising when i open this template( friends_profiles.html ). Please... Help me in this ERROR. What am i missing in this ?
I will really appreciate your HELP.
You are only passing a single object f_profiles in the context to the template, but are trying to iterate over an iterable by doing {% for friends in f_profiles %}.
f_profiles = Profile.objects.get(user=request.user) this will only give you one object which is the profile of the request.user. You are not getting friends of the user with this line of code.
Also, it maybe better to use
f_profiles = get_object_or_404(Profile, user=request.user)
Try to replace this code in the templates:
{% for friends in f_profiles %}
{{ friends.full_name }}
with
{% for friend in f_profiles.friends.all %}
{{ friend.full_name}}
or
{% for friend in f_profiles.get_friends %}
{{ friend.full_name }}

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.