Sum Foreignkey objects to loop - python

I'm trying create a table with 2 columns:
1) Collections and 2) Qualified Sales.
Like the image above.
Each book count the own qualified_sales.
The Qualified sales(column in the table) must sum all qualified_sales of all books of each collection.
models.py
class Publishing_company(models.Model):
title = models.CharField(max_length=50)
class Collection(models.Model):
publishing_company = models.ForeignKey(Publishing_company, on_delete=models.CASCADE)
class Book(models.Model):
publishing_company = models.ForeignKey(Publishing_company, on_delete=models.CASCADE)
class Sale(models.Model):
book = models.ForeignKey(Book, on_delete=models.CASCADE)
qualified_sale = models.IntegerField(default=0)
views.py
def qlf_sales(request):
book = Collection.objects.filter(user=request.user)
qualified_sum = Sale.objects.filter(user=request.user, book__publishing_company__collection__in=book).aggregate(Sum('qualified_sale'))['qualified_sale__sum'] or 0
context = {'qualified_sum': qualified_sum}
return render(request, 'template.html', context)
template.html
{% for collection in collections %}
<tr>
<td>{{collection}}</td>
<td>{{qualified_sum}}%</td>
</tr>
{% endfor %}
But this code not work. Dont appear any debug error, but in the all fields in the Qualified Sales' column appear the same value: the sum of all qualified_sales of all sales of all book.
why didn't separate by collection?
If anyone can help me. Please i go a lot grateful.

Related

printing values django templates using for loop

I have two models interrelated items and broken :
class Items(models.Model):
id = models.AutoField(primary_key=True)
item_name = models.CharField(max_length=50, blank=False)
item_price = models.IntegerField(blank=True)
item_quantity_received = models.IntegerField(blank=False)
item_quantity_available = models.IntegerField(blank=True)
item_purchased_date = models.DateField(auto_now_add=True, blank=False)
item_units = models.CharField(max_length=50, blank=False)
def __str__(self):
return self.item_name
class Broken(models.Model):
item = models.ForeignKey(Items, default=1, on_delete=models.CASCADE)
item_quantity_broken = models.IntegerField(blank=True)
item_broken_date = models.DateField(auto_now_add=True, blank=False)
item_is_broken = models.BooleanField(default=True)
date_repaired = models.DateField(auto_now=True, blank=True)
def __str__(self):
return self.item.item_name
I wrote this view function to retrieve data to a table into a template:
def broken_items(request):
br = Broken.objects.select_related('item').all()
print(br.values_list())
context = {
'title': 'broken',
'items': br,
}
return render(request, 'store/broken.html', context)
this is the executing query:
SELECT "store_broken"."id",
"store_broken"."item_id",
"store_broken"."item_quantity_broken",
"store_broken"."item_broken_date",
"store_broken"."item_is_broken",
"store_broken"."date_repaired",
"store_items"."id",
"store_items"."item_name",
"store_items"."item_price",
"store_items"."item_quantity_received",
"store_items"."item_quantity_available",
"store_items"."item_purchased_date",
"store_items"."item_units"
FROM "store_broken"
INNER JOIN "store_items"
ON ("store_broken"."item_id" = "store_items"."id")
looks like it gives me all the fields I want. In debugger it shows data from both tables,
so I wrote for loop in template,
{% for item in items %}
<tr>
<td>{{item.id}}</td>
<td>{{item.item_id}}</td>
<td>{{item.item_quantity_broken}}</td>
<td>{{item.item_broken_date}}</td>
<td>{{item.item_is_broken}}</td>
<td>{{item.date_repaired}}</td>
<td>{{item.item_name }}</td>
<td>{{item.item_item_quantity_received}}</td>
<td>{{item.item_quantity_available}}</td>
<td>{{item.item_purchased_date}}</td>
<td>{{item.items_item_units}}</td>
</tr>
{% endfor %}
The thing is this loop only gives me data from broken table only. I can't see data from Items table.
can someone help me to find the reason why other details are not showing?
Your items query is of Broken objects. So in order to access the Items values you need to change your table. For better understanding change your view like this:
brokens = Broken.objects.select_related('item').all()
context = {
'title': 'broken',
'brokens ': brokens,
}
and then your table:
{% for broken in brokens %}
<tr>
<td>{{broken.id}}</td>
<td>{{broken.item.pk}}</td> # This is the item id
<td>{{broken.item_quantity_broken}}</td>
<td>{{broken.item_broken_date}}</td>
<td>{{broken.item_is_broken}}</td>
<td>{{broken.date_repaired}}</td>
<td>{{broken.item.item_name}}</td>
<td>{{broken.item.item_quantity_received }}</td>
<td>{{broken.item.item_quantity_available}}</td>
<td>{{broken.item.item_purchased_date}}</td>
<td>{{broken.item.items_item_units}}</td>
</tr>
{% endfor %}
you loop over a List of Broken objects
to access the related item objects
item.item.item_name

Django Passing Through List Items

I have a todo website that allows users to put a remind in a certain list, such as work, school, groceries, etc. However, I'm a bit lost on how to get the list name and their items to display.
Models.py:
class RemindList(models.Model):
parent_user = models.ForeignKey(User, on_delete=models.CASCADE, null=True)
title = models.CharField(max_length=50)
class Reminder(models.Model):
remind_types = [('Regular', 'Regular'), ('Long Term', 'Long Term')]
title = models.CharField(max_length=100)
description = models.TextField()
remind_time = models.DateTimeField(blank=True)
parent_user = models.ForeignKey(User, on_delete=models.CASCADE, null=True)
parent_list = models.ForeignKey(RemindList, on_delete=models.CASCADE, null=True)
type_of_remind = models.CharField(max_length=12, choices=remind_types, default='Regular')
complete = models.BooleanField(default=False)
Views.py:
#login_required(login_url='/login')
def home(request):
user = get_object_or_404(User, username=request.user.username)
context = {
'events': ToDoItem.objects.filter(parent_user=user),
'reminders': Reminder.objects.filter(parent_user=user, type_of_remind='Regular'),
'long_term_reminders': Reminder.objects.filter(parent_user=user, type_of_remind='Long Term'),
'remind_list_items': RemindList.objects.filter(parent_user=user),
}
return render(request, 'main/home.html', context)
I can pass through the list names, and I planned to just loop through them and add Reminder.objects.filter(parent_user=user, type_of_remind='Regular', parent_list=list_name) to context. However, theres no way to loop through them on the html side (can't do for loop because there are other context types), and you can't filter them on the html side (correct me if I'm wrong). Is there another way to do this?
Ok, it took me a few readings, but if what I understand is correct you want to be able to iterate over the ReminderList objects and also list out the Reminder items under each one.
My suggestion would be to add a method to ReminderList that returns the items in that list, you could then do something like this in your template
{% for list in reminder_lists %}
... List header stuff goes here ...
{% for item in list.get_reminder_items %}
... Print the item ...
{% endfor %}
{% endfor %}
(The Django templating language can be a little interesting in that object.identifier can map to either an attribute or an object method - this can be useful for cases like these).

Django 2 distinct model field items

I am trying to get a list of distinct items in a field of a module and then display all the items associated with that field.
For example, in a school administration system there is a school module and a student model. Each student has a color associated with them as a 'color' field. I want to create a page where the page lists all the distinct colors in the school and then under each color a list of students that belong to that color.
Would I write this function in views?
Here is what I have so far in views.py:
class SchoolColorDetailView(DetailView):
model=models.School
template_name='school_app/school_color_detail.html'
def get_context_data(self,**kwargs):
context = super().get_context_data(**kwargs)
context['colors']=Student.objects.all().order_by('color').distinct('color')
This will get me a list of all colors (but not by school). Is there any way to only get the colors by school and then all the students associated with that color? Do I have to create a dictionary for this?
Any help would be appreciated.
Thanks!
Update:
Here are the models:
class School(models.Model):
name = models.CharField(max_length=256)
principal = models.CharField(max_length=256)
location = models.CharField(max_length=256)
def __str__(self):
return self.name
def get_absolute_url(self):
return reverse("school_app:school_detail",kwargs={'pk':self.pk})
class Student(models.Model):
name = models.CharField(max_length=256)
color = models.CharField(max_length=256)
school = models.ForeignKey(School,related_name='students', on_delete="Protect")
def __str__(self):
return self.name
def get_absolute_url(self):
return reverse("school_app:student_detail",kwargs={'pk':self.pk})
Second update:
I am trying to make a template that looks something like this (not sure the best way to do that):
{% for color in colors %}
<ul>
<li>{{color}}
{% for student in color %}
<ul>
<li>{{student}}</li>
</ul>
{% endfor %}
</li>
</ul>
{% endfor %}
Change
context['colors']=Student.objects.all(
).order_by('color').distinct('color')
to
context['colors']=self.student_set.all(
).order_by('color').distinct('color')

Iterating 2 querysets in Django html?

I have two querysets. My first Queryset (services) has all of my service objects. My second Queryset (rating_values) has all of my rating values, where each index corresponds to the index in the services Queryset. For example services[1] corresponds with rating_values[1].
How do I loop through these two queries in an html page in django so so that I can display the service name along with the corresponding rating value?
To be clear, services contains service objects and rating_values contains decimal values. I pass the variables like this:
return render_to_response('services/display_services.html', {'user': request.user, 'services':services, 'rating_values': rating_values })
I would like to do something like this:
{% for service in services %}
<p> {{service.service_name}} : {{ corresponding rating_value}} </p>
Edit
Here is my Service model:
class Service(models.Model):
user_id= models.IntegerField(default=1)
service_name = models.CharField(max_length=100)
address = models.CharField(max_length=200)
def __str__(self): # __unicode__ on Python 2
return self.service_name
Here is my Rating Model:
class Rating(models.Model):
service_id= models.IntegerField(default=1)
service_name= models.CharField(max_length=200)
number_of_ratings = models.IntegerField()
total_rating_value = models.IntegerField()
rating_average = models.FloatField()
def __str__(self): # __unicode__ on Python 2
return self.service_name
Just to answer the original question as well.
If you for some reason don't want a database relation between the models, you could convert the querysets to lists and zip them in the view, turning the querysets to a list of tuples.
view:
return render_to_response(
'services/display_services.html',
context_instance={
'user': request.user,
'services_and_ratings': zip(
services.all(),
rating_values.all()
)
}
)
template:
{% for service, rating in services_and_ratings %}
<p> {{ service.service_name }} : {{ rating.rating_average }} </p>
You can establish the relationship right in the model.
class Rating(models.Model):
service= models.OneToOneField(Service, primary_key=True)
service_name= models.CharField(max_length=200)
number_of_ratings = models.IntegerField()
total_rating_value = models.IntegerField()
rating_average = models.FloatField()
....
You can then pass services and get the corresponding ratings..
{% for service in services %}
<p> {{service.service_name}} : {{ service.rating.rating_average }} </p>

Django model ordering issue

This is my model:
class Feature(models.Model):
name = models.CharField(max_length=75, blank=True)
order = models.SmallIntegerField()
group = models.ForeignKey(FeatureGroup)
def __unicode__(self):
return self.name
class Meta:
ordering = ['order']
The "Features" are being correctly display in the admin control panel based on the value specified in "order".
I have this in my view:
p = get_object_or_404(Phone.objects.prefetch_related('brand', 'features__feature', 'photo_set'), id=id)
I templates I have {% for feature in phone.features.all %}... {{ feature.feature }} ...
The values are being displayed correctly but in random order.
What's wrong and how can I overcome this problem?
Thanks.
How about the template filter dictsort
https://docs.djangoproject.com/en/dev/ref/templates/builtins/#dictsort
{% for feature in phone.features.all|dictsort:"order" %}

Categories