I would like to display sum all the distinct categories of the products that belongs to the user. I searched on the web, but all the things that I tried doensn't work. You may find the models,view and template below. It doesn't give me anything at the html.
Model:
class Product(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE,related_name='products')
category = models.CharField(max_length=120)
brand = models.CharField(max_length=120)
product = models.CharField(max_length=120)
price = models.DecimalField(decimal_places=2,max_digits=100)
class Comp_Product(models.Model):
product = models.ForeignKey(Product,on_delete=models.CASCADE, related_name="comp_products")
competitor = models.URLField()
price = models.DecimalField(decimal_places=2,max_digits=100)
change = models.FloatField()
stock = models.BooleanField()
last_update = models.DateField(auto_now_add=True)
View:
class DashboardList(ListView):
template_name='dashboard_by_user.html'
def get_queryset(self):
return Product.objects.filter(user=self.request.user).annotate(count_category=Count('category',distinct=True)).aggregate(sum_category=Sum('count_category'))
template:
{% for product in product_list %}
{{product.sum_category}}
{%endfor%}
welcome to stackoverflow,
I'm assuming that you want to count the number of distinct categories for the given user. This can be done like this:
views.py:
from django.views.generic.list import ListView
from .models import Product
class DashboardList(ListView):
template_name = 'dashboard_by_user.html'
def get_queryset(self):
return Product.objects.filter(user=self.request.user)
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
Products = context['object_list']
context['distinct_category_count'] = Products.values(
'category').distinct().count()
return context
dashboard_by_user.html:
<h1>Products</h1>
<ul>
{% for product in object_list %}
<li>{{ product.brand }} - {{ product.product }} - {{ product.category }}</li>
{% empty %}
<li>No Producs yet.</li>
{% endfor %}
</ul>
<p> Number of distinct categories: {{ distinct_category_count }} </p>
This should give you an output similar to this one:
Related
This is my 2nd week learning Django. I'm trying to get comfortable with Django Template Language. I'm trying to make an Inventory app with 4 models. The views for them are class-based.
The templates for Ingredient and Menu work as expected. However, I'm struggling with trying to loop through values from the Purchase model which has a foreign key field 'menu_item'. The template is not showing anything from the for loop. I've referred numerous articles here to find most of them use function-based views. I've tried using {% for purchase in purchase_set %}, {% for purchase in purchase_set.all %}. I know the object to iterate over is a query-set. I cannot figure out what to do?
MODELS.PY
from django.db import models
# Create your models here.
class Ingredient(models.Model):
Pounds = 'lbs'
Ounces = 'oz'
Grams = 'gms'
Eggs = 'eggs'
Piece = 'piece'
Litre = 'litre'
unit_choices = [(Pounds, 'lbs'),
(Ounces, 'ounces'),
(Grams, 'grams'),
(Eggs, 'eggs'),
(Piece, 'piece'),
(Litre, 'litre')]
id = models.AutoField(primary_key=True)
name = models.CharField(max_length=50)
unit_price = models.FloatField(default=0.0)
quantity = models.FloatField(default=0.0)
unit = models.CharField(max_length=10, choices=unit_choices)
class Meta:
ordering = ['id']
def __str__(self):
return self.name
class MenuItem(models.Model):
id = models.AutoField(primary_key=True)
title = models.CharField(max_length=50)
price = models.FloatField(default=0.0)
class Meta:
ordering = ['id']
def __str__(self):
return self.title
class RecipeRequirement(models.Model):
menu_item = models.ForeignKey(MenuItem, on_delete=models.CASCADE)
ingredient = models.ForeignKey(Ingredient, on_delete=models.CASCADE)
quantity = models.FloatField(default=0.0)
def __str__(self):
return self.menu_item.title
class Purchase(models.Model):
menu_item = models.ForeignKey(MenuItem, on_delete=models.CASCADE)
timestamp = models.DateTimeField()
id = models.AutoField(primary_key=True)
class Meta:
ordering = ['id']
def __str__(self):
return self.menu_item.title
VIEWS.PY:
from django.shortcuts import render
from .models import Ingredient, MenuItem, RecipeRequirement, Purchase
from django.views.generic import ListView
def home(request):
return render(request, 'inventory/home.html')
class IngredientView(ListView):
model = Ingredient
template_name = 'inventory/ingredients.html'
class PurchaseView(ListView):
model = Purchase
template_name = 'inventory/purchases.html'
class MenuView(ListView):
model = MenuItem
template_name = 'inventory/menu.html'
PURCHASES.HTML
<h3>This is purchases page.</h3>
{% block content %}
<table>
{% for purchase in purchase_set.all %}
<tr>
<td>{{ purchase.title }}</td>
</tr>
{% endfor %}
</table>
{% endblock %}
The title field you are trying to show is in MenuItem model that is used as foreignkey in Purchase model with menu_item field. ListView class returns to context yours purchases in object_list key. So in Your purchases.html template:
<h3>This is purchases page.</h3>
{% block content %}
<table>
{% for purchase in object_list %}
<tr>
<td>{{ purchase.menu_item.title }}</td>
</tr>
{% endfor %}
</table>
{% endblock %}
PS. This `purchase_set' is referring to reverse relationship. So if you would want to show all purchases of MenuItem you would do:
{% for item in menuitems %}
<h1>{{ item }}</h1>
{% for purchase in item.purchase_set.all %}
<p>{{ purchase.timestamp }}</p>
{% endfor %}
{% endfor %}
I want to display an unordered list of NBA teams from my teams table database. Within each team, I want an ordered list of players on that team. So basically I want to produce a list of all objects from my parent table and for each object from the parent table I want a list of all objects from the child table related the parent table. I understand that the problem is methods are not allowed in template tagging, so 'team.players_set.all()' would not be allowed. How else can I get the results that I want?
class Teams(models.Model):
name = models.CharField(max_length=20, unique=True)
num_of_plyrs = models.IntegerField()
def __str__(self):
return f"{self.name} have {self.num_of_plyrs} players."
class Meta:
verbose_name_plural = "Teams"
class Players(models.Model):
name = models.CharField(max_length=20)
team = models.ForeignKey(Teams, on_delete=models.CASCADE)
def __str__(self):
return f"{self.name} plays for {self.team}"
class Meta:
verbose_name_plural = 'Players'
__________________________________________________________________________________
def teams(request):
teams = Teams.objects.all()
context = {'teams': teams}
return render(request, 'one_app/teams.html', context)
__________________________________________________________________________________
<h3>NBA Teams</h3>
<ul>
{% for team in teams %}
<li>
<p>Team: {{ team.name }}</p>
<p>Number of players: {{ team.num_of_plyrs }}</p>
<ol>
{% for plyr in team.players_set.all() %}
<li>{{ plyr.name }}</li>
{% endfor %}
</ol>
</li>
{% empty %}
<li>There are no teams listed.</li>
{% endfor %}
</ul>
{% for player in team.players_set.all %}
table name should be singular
you can set related_name and use players instead players_set
team = models.ForeignKey(Teams, related_name='players',on_delete=models.CASCADE)
make use of select_related
One way to achieve this is:
class PlayersView(ListView):
model = Team
...
def get_queryset(self, **kwargs):
teams = []
queryset = super().get_queryset()
for team in queryset:
players = team.player_set.all()
for player in players:
teams.append([team, (player.name, ...)]
return teams
And in your template:
{% for team, players in teams %}
...
{% for player in players %}
...
{% endfor %}
{% endfor %}
ALTERNATIVE
If you know this is something you might be using a lot and to simplify your view, you can also create a manager:
from your_app.managers import TeamManager
class Team(models.Model):
...
objects = Manager()
team_manager = managers.TeamManager.as_manager()
...
In a file manager.py or anything you want:
from django.db.models import QuerySet
class TeamManager(QuerySet):
def table_queryset(self):
queryset = self.all()
teams = []
for team in queryset:
players = team.player_set.all()
for player in players:
teams.append([team, (player.name, ...)]
return teams
And then in your view:
class PlayersView(ListView):
model = Team
queryset = Team.player_manager.table_queryset()
How to get all product for every order on Templates. Please help me
Model.py
class Order(models.Model):
customer_id= models.ForeignKey(Customers )
delivery_add_id= models.ForeignKey(DeliveryAddresses)
class OrderItem(models.Model):
order_id = models.ForeignKey(Order, related_name='orderId')
product_id = models.ForeignKey('Products', related_name='productId')
class Products(models.Model):
cat_id = models.ForeignKey('Categories')
name = models.CharField(max_length=200)
price = models.FloatField()
Templates
<tr>
<th>Product ordered</th>
<td>
<ul>
{% for prod in order.orderId.productId.product_set.all%}
<li>{{pro}}</li>
{% endfor %}
</ul>
{{order.orderId.productId.product_set.all}}
</td>
</tr>
https://i.stack.imgur.com/XJ3zG.png
Views.py
class productList(ListView):
model= Products
context_object_name = 'product_list'
def get_queryset(self):
return Products.objects.all()
class productDetail(DetailView):
context_object_name = 'product'
model = Products
queryset = Products.objects.all()
class orderList(ListView):
model = Order
context_object_name= 'order_list'
def get_queryset(self):
return Order.objects.all()
class orderDetail(DetailView):
context_object_name ='order'
model = Order
queryset= Order.objects.all()
This is the general relationship I have set up.I'm trying to do is, in a templates, i want to show all product for every order. Order-product : many to many relationship. Please help me
It should be like this:
{% for orderItem in order.orderId.all %}
{% for pro in orderItem.productId.all %}
<li>{{pro}}</li>
{% endfor %}
{% endfor %}
Here are my two models
class Category(models.Model):
name = models.CharField(max_length = 50)
description = models.CharField(max_length = 1000)
created = models.DateTimeField(auto_now_add=True)
def __unicode__(self, ):
return self.name
class Post(models.Model):
subject = models.CharField(max_length=50, blank=True)
description = models.CharField(max_length=1000)
created = models.DateTimeField(auto_now_add=True)
category = models.ManyToManyField(Category)
def __unicode__(self, ):
return self.subject
I'm displaying the subject, description, and date of each post in a template. But I also want to display the respective category for each post as well.
Here's the part of my view
def index(request):
posts = Post.objects.order_by("-created")
return render(request,'posts/index.html', {'posts':posts})
and then how I'm trying to display it in a template:
{% for post in posts %}
<div>
{{ post.subject }}<br />
{{ post.description }}<br />
{{ post.created }} | of {{ post.category }}
</div>
{% endfor %}
But the category will not show up, all I get is
<django.db.models.fields.related.ManyRelatedManager object at 0x7ff7e40a0c90>
I've tried doing post.category.name and other random combinations but it either gives nothing or a parsing error. I have no idea how to get the category displayed.
That's a Manager. Use it as you would any other Manager (e.g. Post.objects).
{% for category in post.category.all %}
I seem to have a problem displaying work orders. in my app. The clients does not have the same problem so why does the work orders not show up. Actually it is as almost as a black space appears rather than text that should appear from my database.
The problem seems to be because work orders have a many-to-many field. If I have {{work_orders}}instead of say `{{work_orders.description}}, I get this
<django.db.models.fields.related.ManyRelatedManager object at 0xa042c6c>
Here are some output from my app.
#views
#login_required
def invoice_details(request, id=1):
invoices_list = Invoice.objects.filter(pk=id)
client = invoices_list[0].client
work_orders = invoices_list[0].work_orders
return render_to_response(('invoice_details.html', locals()), {'work_orders': work_orders,'client': client, 'invoices_list': invoices_list}, context_instance=RequestContext(request))
#models.py
class Invoice(models.Model):
client = models.ForeignKey(Client)
date = models.DateField()
invoice_no = models.CharField(max_length=16)
work_orders = models.ManyToManyField(Work_Order)
contract_info = models.ForeignKey(Contract_Info)
def __unicode__(self):
return self.invoice_no
#invoice_details.html
{{client.company}}<br/>
{{client.address}}<br/>
{{client.city}}<br/>
{{client.postcode}}<br/>
{{work_orders.description}}<br/>
{{work_orders.quantity}}<br/>
{{work_orders.item_no}}<br/>
should it not be work_orders.all, e.g.
{% for work_order in work_orders.all %}
{{work_order.description}}
{% endfor %}
#views
from django.shortcuts import get_object_or_404
#login_required
def invoice_details(request, id=1):
invoice = get_object_or_404(Invoice, pk=id)
return render_to_response(('invoice_details.html', locals()), {'invoice': invoice}, context_instance=RequestContext(request))
#models.py
class Invoice(models.Model):
client = models.ForeignKey(Client)
date = models.DateField()
invoice_no = models.CharField(max_length=16)
work_orders = models.ManyToManyField(Work_Order)
contract_info = models.ForeignKey(Contract_Info)
def __unicode__(self):
return self.invoice_no
#invoice_details.html
{{ invoice.client.company }}<br/>
{{ invoice.client.address }}<br/>
{{ invoice.client.city }}<br/>
{{ invoice.client.postcode }}<br/>
{% for work_order in invoice.work_orders.all %}
{{ work_order.description }}<br/>
{{ work_order.quantity }}<br/>
{{ work_order.item_no }}<br/>
{% endfor %}