I want to show the calculated discount under every product. The code below has no errors, but it does not display the value.
models.py:
from django.db import models
# Create your models here.
CATEGORIES = (
('Electronics', 'Electronics'),
('Clothing', 'Clothing'),
)
class Products(models.Model):
Image = models.FileField()
ProductName = models.CharField(max_length = 250, default='')
Brand = models.CharField(max_length = 250, default='')
OriginalPrice = models.IntegerField(default = '')
Price = models.IntegerField(default = '')
Category = models.CharField(max_length = 250, choices = CATEGORIES)
class Meta:
verbose_name = 'Product'
verbose_name_plural = 'Products'
def DiscountCalc(self):
Discount = (Price/OriginalPrice) * 100
return self.Discount
def __str__ (self):
return self.ProductName
This is the template
index.html:
{% for product in AllProducts %}
<article class="product col-sm-3">
<a href="#" class="prodlink">
<img src="{{ product.Image.url }}" class="prodimg img-responsive">
<p class="prodname">{{ product.ProductName }}</p>
<span class="origprice">₹{{ product.OriginalPrice }}</span>
<span class="price">₹{{ product.Price }}</span>
<div class="discount">
<p>{{ product.Discount }}% off</p>
</div>
</a>
</article>
{% endfor %}
you need to make a property :
#property
def Discount(self):
return (self.Price/self.OriginalPrice) * 100
So now you can use product.Discount :)
Docs here Django model-methods
1)Defining a local variable and Returning a class variable will return null
2)You have to have the same name in models and template
models.py
def DiscountCalc(self):
Discount = (Price/OriginalPrice) * 100
return Discount
index.html
{% for product in AllProducts %}
<article class="product col-sm-3">
<a href="#" class="prodlink">
<img src="{{ product.Image.url }}" class="prodimg img-responsive">
<p class="prodname">{{ product.ProductName }}</p>
<span class="origprice">₹{{ product.OriginalPrice }}</span>
<span class="price">₹{{ product.Price }}</span>
<div class="discount">
<p>{{ product.DiscountCalc }}% off</p>
</div>
</a>
</article>
{% endfor %}
Related
template.html
{% for portfolioList in portfolio_list %}
<div class="jobster-timeline-item">
<div class="jobster-timeline-cricle">
<i class="far fa-circle"></i>
</div>
<div class="jobster-timeline-info">
<div class="dashboard-timeline-info">
<div class="dashboard-timeline-edit">
<ul class="list-unstyled d-flex">
<li><a class="text-right" href="{% url 'MyPortfolioUpdate' post_id=portfolioList.idx %}" role="button"> <i class="fas fa-pencil-alt text-info mr-2"></i> </a></li>
<li><i class="far fa-trash-alt text-danger"></i></li>
</ul>
</div>
<span class="jobster-timeline-time">{{portfolioList.start_date|date:"Y년 m월"}} ~ {{portfolioList.end_date|date:"Y년 m월"}}</span>
<h6 class="mb-2">{{portfolioList.subject}}</h6>
<span>-{{portfolioList.client_name}}</span>
<p class="mt-2">{{portfolioList.content|linebreaksbr}}</p>
<div class="row">
{% for portfolioImgList in portfolio_img_list %}
{% if portfolioImgList.portfolio_idx.idx == portfolioList.idx %}
<div class="col-md-6">
<img class="img-fluid" src="{{portfolioImgList.file.url}}" alt="" >
</div>
{% endif %}
{% endfor %}
</div>
</div>
</div>
</div>
{% endfor %}
view.py
q = Q()
q &= Q(user_idx = request.user.id)
portfolio_list = UserPortfolio.objects.filter(q).order_by('-idx')
q = Q()
q &= Q(portfolio_idx__user_idx = request.user.id)
portfolio_img_list = UserPortfolioFile.objects.filter(q).order_by('-idx')
return render(request, 'account/setting/portfolio_list.html', {"portfolio_list":portfolio_list, "portfolio_img_list":portfolio_img_list}
model.py
class UserPortfolio(models.Model):
idx = models.AutoField(primary_key=True)
user_idx = models.ForeignKey(
User,
db_column='user_idx',
on_delete=models.CASCADE
)
subject = models.CharField(max_length=255)
client_name = models.CharField(max_length=255)
client_service = models.CharField(max_length=255)
client_category = models.CharField(max_length=255)
start_date = models.DateTimeField()
end_date = models.DateTimeField()
content = models.TextField()
write_date = models.DateTimeField(auto_now = True)
update_date = models.DateTimeField(auto_now = True)
is_file = models.CharField(max_length=1)
class Meta:
managed = False
db_table = 'account_user_portfolio'
def portfolio_upload_to(instance, filename):
nowDate = datetime.now().strftime("%Y/%m/%d")
return '/'.join([str(instance.portfolio_idx.user_idx), instance.folder , nowDate, filename])
class UserPortfolioFile(models.Model):
idx = models.AutoField(primary_key=True)
portfolio_idx = models.ForeignKey(
UserPortfolio,
db_column='portfolio_idx',
on_delete=models.CASCADE
)
folder = 'portfolio'
file = models.ImageField(upload_to=portfolio_upload_to)
class Meta:
managed = False
db_table = 'account_user_portfolio_file'
This is result.
I want to use join orm in view.py. not like this. used 'if' in template.py
How can I do this? And I tried use join sql. but It was not worked.
I used prefetch_related this. but Its result was same as now.
And I think This is maybe good. doesn't?
Please answer something and thanks to every one
You can enumerate with .userportfoliofile_set.all:
{% for portfolioImgList in portfolioList.userportfoliofile_set.all %}
…
{% endfor %}
this will make a query to only retrieve the UserPortfolioFiles related to the portfolioList object.
In the view you can work with .prefetch_related(…) [Django-doc] to fetch all related items with one query, so:
def some_view(request):
portfolio_list = UserPortfolio.objects.filter(
user_idx=request.user.id
).prefetch_related('userportfoliofile_set').order_by('-idx')
return render(request, 'account/setting/portfolio_list.html', {'portfolio_list':portfolio_list})
I have a list of categories as well as a list of products my template is in such a manner that it has category sections each with a display of products that belong to said categories. I created a for loop for categories so as to easily display category sections for each category I create. I then went on to create a forloop for products within the category forloop with a condition so as to match products with their actual category before they are displayed under their category section. how can I slice the resulting products to limit the number of products shown
Models.py
class Category(models.Model):
name = models.CharField(max_length=120)
image_263x629 = models.ImageField(upload_to='cat_imgs')
image_263x629_2 = models.ImageField(upload_to='cat_imgs')
image_263x629_3 = models.ImageField(upload_to='cat_imgs')
img_array = [image_263x629, image_263x629_2, image_263x629_3]
description = models.CharField(max_length=250)
def __str__(self):
return self.name
class SubCategory(models.Model):
name = models.CharField(max_length=200)
description = models.CharField(max_length=300)
category = models.ForeignKey(Category, on_delete=models.CASCADE)
def __str__(self):
return self.name
#def get_absolute_url(self):
# return reverse('subcat_detail', args=[str(self.id)])
class Product(models.Model):
name = models.CharField(max_length=120)
price = models.FloatField()
image_182x182 = models.ImageField(upload_to='pdt_imgs/')
image_1200x1200 = models.ImageField(upload_to='pdt_imgs/alt_imgs/')
image_600x600 = models.ImageField(upload_to='pdt_imgs/alt_imgs/')
image_600x600_2 = models.ImageField(upload_to='pdt_imgs/alt_imgs/')
image_300x300 = models.ImageField(upload_to='pdt_imgs/alt_imgs/')
img_array = [image_1200x1200, image_600x600, image_600x600_2]
sku = models.IntegerField()
available = models.BooleanField(default=True)
discount = models.IntegerField(default = 0)
description = models.CharField(max_length=120, blank=True, null=True)
brand = models.CharField(max_length=120, blank=True, null=True)
category = models.ForeignKey(SubCategory, on_delete=models.CASCADE)
seller = models.ForeignKey(Seller, on_delete=models.CASCADE)
Views
class HomePageView(ListView):
model = SubCategory
template_name = 'home.html'
queryset = SubCategory.objects.all()
def get_context_data(self, **kwargs):
context = super(HomePageView, self).get_context_data(**kwargs)
context['products'] = Product.objects.all()
context['pdts'] = Product.objects.order_by('?')[:12]
context['categories'] = Category.objects.all()
context['subcategories'] = SubCategory.objects.all()
return context
Template
{% for category in categories %}
<div class="ps-block--products-of-category">
<div class="ps-block__categories">
<h3>{{ category.name }}</h3>
<ul>
{% for subcategory in subcategories %}
{% if subcategory.category.name == category.name %}
<li>{{ subcategory.name }}</li>
{% endif %}
{% endfor %}
</ul><a class="ps-block__more-link" href="{% url 'cat_detail' category.id %}">View All</a>
</div>
<div class="ps-block__slider">
<div class="ps-carousel--product-box owl-slider" data-owl-auto="true" data-owl-loop="true"
data-owl-speed="7000" data-owl-gap="0" data-owl-nav="true" data-owl-dots="true" data-owl-item="1"
data-owl-item-xs="1" data-owl-item-sm="1" data-owl-item-md="1" data-owl-item-lg="1" data-owl-duration="500"
data-owl-mousedrag="off">
<img src="{{ category.image_263x629.url }}" alt="">
<img src="{{ category.image_263x629_2.url }}" alt="">
<img src="{{ category.image_263x629_3.url }}" alt="">
</div>
</div>
<div class="ps-block__product-box">
{% for product in products %}
{% if product.category.category.name == category.name %}
<div class="ps-product ps-product--simple">
<div class="ps-product__thumbnail"><a href="{% url 'pdt_detail' product.id %}"><img src="{{ product.image_300x300.url }}"
alt=""></a>
{% if product.discount > 0 %}
<div class="ps-product__badge">-{{ product.discount }}%</div>
{% endif %}
{% if product.available == False %}
<div class="ps-product__badge out-stock">Out Of Stock</div>
{% endif %}
</div>
<div class="ps-product__container">
<div class="ps-product__content" data-mh="clothing"><a class="ps-product__title"
href="{% url 'pdt_detail' product.id %}">{{ product.name }}</a>
<div class="ps-product__rating">
<select class="ps-rating" data-read-only="true">
<option value="1">1</option>
<option value="1">2</option>
<option value="1">3</option>
<option value="1">4</option>
<option value="2">5</option>
</select><span>01</span>
</div>
<p class="ps-product__price sale">UGX{{ product.price }}</p>
</div>
</div>
</div>
{% endif %}
{% endfor %}
</div>
</div>
{% endfor %}
Please do not filter in the template. You should filter in the view. A template implements rendering logic, not business logic*.
You can filter and slice in the view with:
def my_view(request):
# …
products = Product.objects.filter(category__name='specified category')[:10]
context = {
'products': products
}
return render(request, 'my_template.html', context)
This is not only the place where filtering belongs, it is also more efficient since we here will filter and slice on the database side. Typically a database can do this more efficient, and it furthermore limits the bandwidth from the database to the Django/Python layer.
Note (based on #SLDem's comment):
If you aim to filter children, you make use of a Prefetch object [Django-doc]. Indeed, imagine that we have a QuerySet of Categorys and we want to only retain Products that are available, we can use:
from django.db.models import Prefetch
categories = Category.objects.prefetch_related(
Prefetch(
'product_set',
Product.objects.filter(available=True),
to_attr='available_products'
)
)
then in the template we can render this with:
{% for category in categories %}
{% for product in category.available_products %}
…
{% endfor %}
{% endfor %}
I am learning Django for the last couple of months. Now I am working on a demo project which is about teachers those who will be available to teach preferred subject. But after working some days I can't move ahead of some limitations of my programming knowledge. I want to show a button on some selected posts. I used FOR loop to create the post model, and inside it I also used an IF statement. But it is not working the way I wanted. I want the button will only be shown when a teacher available. Can you guys please help me to get rid of this problem? Thanks in advance!
In the Post model I have included some Boolean fields and set their default values as False. And in the blog view I have created some querysets for those Boolean fields to call them when they are needed. When I use them inside the HTML I don't get any error. Please look the code bellow.
Here is the Teacher model for teacher app
from django.db import models
from django.utils import timezone
from PIL import Image
class Teacher(models.Model):
name = models.CharField(max_length = 100)
teacher_photo = models.ImageField(upload_to = 'photos/%Y/%m/%d/')
description = models.TextField()
teacher_govt_id = models.CharField(unique = True ,max_length = 20)
phone = models.CharField(unique = True ,max_length = 20)
nid = models.CharField(unique = True ,max_length = 14)
email = models.CharField(max_length = 50)
is_selected = models.BooleanField(default = False)
join_date = models.DateTimeField(default = timezone.now)
def __str__(self):
return self.name
def save(self):
super().save()
img = Image.open(self.teacher_photo.path)
if img.height > 300 or img.width > 300:
output_size = (300, 300)
img.thumbnail(output_size)
img.save(self.teacher_photo.path)
Here is the Post model for blog app
# from django.forms import ModelForm
from django.db import models
from django.utils import timezone
from django.contrib.auth.models import User
from teacher.models import Teacher
class Post(models.Model):
teacher = models.ForeignKey(Teacher, on_delete = models.DO_NOTHING, blank=True, null=True)
author = models.ForeignKey(User, on_delete = models.CASCADE)
title = models.CharField(max_length = 100)
clip = models.FileField(upload_to = 'videos/%Y/%m/%d/')
description = models.TextField(max_length = 2400)
publish = models.DateTimeField(default = timezone.now)
created = models.DateTimeField(auto_now_add = True)
updated = models.DateTimeField(auto_now = True)
is_published = models.BooleanField(default = True)
is_group = models.BooleanField(default = False)
is_private = models.BooleanField(default = False)
is_available = models.BooleanField(default = False)
def __str__(self):
return self.title
Here is the View for post
from django.shortcuts import render
from . models import Post
from teacher.models import Teacher
def post_list(request):
posts = Post.objects.order_by('-publish').filter(is_published = True)
# get teacher
teacher_available = Post.objects.filter(is_available = True)
assigned_private_teacher = Post.objects.all().filter(is_private = True)
assigned_group_teacher = Post.objects.all().filter(is_group = True)
teacher_selected = Teacher.objects.filter(is_selected = True)
context = {
'posts': posts,
'teacher_available': teacher_available,
'assigned_private_teacher': assigned_private_teacher,
'assigned_group_teacher': assigned_group_teacher,
'teacher_selected': teacher_selected
}
return render(request, 'blog/home.html', context)
Here is the HTML
{% extends 'base.html' %}
{% load static %}
{% block content %}
<a class="skip-link screen-reader-text" href="#content">Skip to content</a>
<!-- <div class="badge"></div> -->
<main id="content" class="main-area">
{% for post in posts %}
<section class="main-content">
<div class="teacher-student">
<div class="teacher">
<img src="{% static 'img/headshot.jpg' %}" alt="">
<!-- <p>TEACHER</p> -->
{{ post.author.get_full_name }}
<small>{{ post.publish }}</small>
</div>
<div class="available">
{% if teacher_available %}
Teacher Available
{% endif %}
</div>
</div>
<div class="main-article">
<a href="detail.html">
<h1>{{ post.title }}</h1>
</a>
<video playsinline oncontextmenu="return false;" controls preload="metadata" controlsList="nodownload"
disablePictureInPicture src="{{ post.clip.url}}" type='video/mp4'>
</video>
<article>
<p>
Lorem ipsum dolor sit amet consectetur, adipisicing elit. Asperiores magni eveniet
praesentium esse molestias iusto doloremque ducimus nobis ex hic. Natus, ipsum...
</p>
</article>
<div class="total-like-share">
<p class="like"><span>Like 400</span></p>
<p class="share"><span>Comments 4000</span></p>
</div>
</div>
</section>
{% endfor %}
</main>
<!-- Left Side Bar -->
<aside class="sidebar-left">
<div class="left-sidebar">
<h2 class="left-sidebar-title">Result Board</h2>
<div class="updates-contens">
<p>Recent Results</p>
<p>Old Results</p>
</div>
</div>
</aside>
<!-- Right Side Bar -->
<aside class="sidebar-right">
<div class="right-sidebar">
<h2 class="right-sidebar-title">Post Updates</h2>
<div class="updates-contens">
<p>Latest Posts</p>
<p>Most comented posts</p>
<p>Most shared posts</p>
</div>
</div>
</aside>
{% endblock content %}
You don't need to send teacher_available via context, you can access in post variable:
<div class="available">
{% if post.is_available %}
Teacher Available
{% endif %}
</div>
Also, {% if teacher_available %} won't work because you are sending a queryset via that variable. If you want to check if there is any value exists in queryset then use .exists. For example:
# in template
{% if teacher_selected.exists %}
# in python
if teacher_selected.exists():
Finally, you don't need to send teacher_available, assigned_private_teacher, assigned_group_teacher via context, because you can access these values from posts, like this:
{% for post in posts %}
{% if post.is_avalilable %}
// do something
{% endif %}
{% if post.is_private %}
// do something
{% endif %}
{% if post.is_group %}
// do something
{% endif %}
{% if post.is_selected %}
// do something
{% endif %}
{% endfor %}
To product page of my project I need to add paginator. I did according to the Django Documentation but I have the following error:
object of type 'InsuranceProducts' has no len()
Here is the my views.py:
def farmer_types(request, type_id):
product_areas = InsuranceProducts.objects.filter(product_type="Фермерам")
product_types = get_object_or_404(InsuranceProducts, id=type_id)
paginator = Paginator(product_types, 6)
page = request.GET.get('page')
types = paginator.get_page(page)
context = {'product_types': product_types,
'product_areas': product_areas,
'types': types}
return render(request, 'insurance_products/farmer/farmer_types.html', context)
Here is the my models.py:
class InsuranceProducts(models.Model):
product_area = models.CharField(max_length=100)
product_description = models.TextField()
product_type = models.CharField(max_length=50)
def __str__(self):
return "{}-{}".format(self.product_area, self.product_type)
class ProductType(models.Model):
product_area = models.ForeignKey(InsuranceProducts, on_delete=models.CASCADE)
title = models.CharField(max_length=100)
description = models.TextField()
body = HTMLField('Content')
def __str__(self):
return "{} - {}".format(self.product_area, self.title)
Here is the code from the template:
{% for product in types.producttype_set.all %}
<div class="btmspace-80">
<h3>{{ product.title|upper }}</h3>
<img class="imgr borderedbox inspace-5" src="{% static 'img/imgr.gif' %}" alt="">
<p>
{{ product.description|upper }}
</p>
<p>
Подробно вы можете узнать о новости здесь</a>
</p>
</div>
{% endfor %}
<div class="pagination">
<span class="step-links">
{% if types.has_previous %}
« first
previous
{% endif %}
<span class="current">
Page {{ types.number }} of {{ types.paginator.num_pages }}.
</span>
{% if types.has_next %}
next
last »
{% endif %}
</span>
</div>
<!-- ################################################################################################ -->
</div>
I did the everything as it is given in the Docs.
Why is product_types plural if you are using get_object_or_404, which returns only one object?
You're doing the pagination right, but doing the query wrong. If you change paginator = Paginator(product_types, 6) to paginator = Paginator(product_areas, 6), you will see that it works perfectly fine.
You should read the documentation on how to do queries, and understand the relationships between models.
I am trying to display fields from child model 'usertraining' entry linked by foreign key to a 'training' entry. but second queryset usertraining_set does not seem to contain anything. What am I missing?
I have the following template loop:
{% for training in training_list %}
{% for elem in training.usertraining_set.all %}
<div class="training">
<div class="training-info">
<div class="training-main-title">
<div class="training-state">{{ elem.state }}</div>
{{ training.title }}
</div>
<div class="training-date">
<p>Last trained: {{ elem.last_training_date|date:"D, d M Y, H:i:s" }}</p>
</div>
<div class="training-score">
Score: <span class="badge btn-circle">{{elem.score}}</span>
</div>
</div>
<img src="{{ training.title_pic.url }}">
</div>
{% endfor %}
{% endfor %}
model
class Training(models.Model):
title = models.CharField(max_length = 2000, blank = False)
title_pic = models.ImageField(upload_to = 'training/title_pics', blank = False)
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse("training_detail",kwargs={'pk':self.pk})
#property
def title_pic_url(self):
if self.title_pic and hasattr(self.title_pic, 'url'):
return self.title_pic.url
class UserTraining(models.Model):
user = models.ForeignKey(User,related_name='usertraining',on_delete=models.CASCADE)
training = models.ForeignKey(Training,related_name='usedtraining',on_delete=models.CASCADE)
state = (
('train', 'train'),
('training', 'training...'),
('retrain', 'retrain'),
('trained','trained')
)
state = models.CharField(max_length = 200, choices = state, default = 'train')
last_training_date = models.DateTimeField(auto_now=True)
score = models.CharField(max_length = 4, default = '0%')
def __str__(self):
""" String representation of Training entry """
return "{}_{}".format(self.user,self.training)
You're using "related_name" in your UserTraining model fields:
user = models.ForeignKey(User,related_name='usertraining',on_delete=models.CASCADE)
training = models.ForeignKey(Training,related_name='usedtraining',on_delete=models.CASCADE)
_set postfix is used only when field has no related name, so in your templates it would be:
{% for elem in training.usertraining.all %}