0

I have a simple model that collects data (specifically integers) to display an election results in a table. I have 2 regions (more of course but let's say two for now) where data will be coming from. I want to display each regions and the total for each region and then display the SUM at the bottom of the table

My base model is as follows;

class Results(models.Model)
    region_number = models.Foreignkey(Regions)
    region_name = models.Charfield()
    polling_station = models.Charfield()
    party1 = models.IntegerField()
    party2 = models.IntegerField()
    party3 = models.IntegerField()

Then I have two class inheritance

class GeneralElections(Results)
    pass

class RegionalElections(Results)
    pass

And I want the printed output in my template to look something like this

---------------------------------
regions   party1   party2  party3
---------------------------------
1         20       40      60
2         20       80      100
---------------------------------
Total     80       120     160    <------- More Importantly This!
---------------------------------

Additionally I want to be able to have summary page that shows

   General Elections
-----------------------
party1   party2  party3
-----------------------
80       120     160


   Regional Elections
-----------------------
party1   party2  party3
-----------------------
50       85      210

Up to this point I have been able to accomplish everything, except being able to print the SUM of each column at the bottom of the table

Everywhere I've looked it said to use django aggregation. However the instructions are a bit vague. Maybe because I am a beginner. I am confused where to put the respective codes for example.

from django.db.import SUM

  1. Where does this import go? In models.py? or views.py?

total = Tally.objects.aggregate(Sum("field_name"))

  1. Where do I put this function?

  2. Which field_name do I use? The are multiple field names I want SUM for. One for each party

I apologize if this has been answered before but I am strapped for time and I couldn't find any detailed information regarding this.

I greatly appreciate if someone can point me in the right direction and save me a lot of time as I need to get this app online in a matter of hours.

Thank you in advance!

  • Aggregate is more of an `over the period` results and I think what you're looking for is `annotate` but of course you can still combine `aggregate` and `annotate` to get "Sum of particular polling_station". – Raja Simon Feb 27 '20 at 07:12

1 Answers1

0

For sum per fields you can use something like:

from django.db.models import Sum

agrregated_results = Results.objects.filter(# if you have any).agrregate(Sum('party1'), Sum('party2'), Sum('party3'))
party1_sum = agrregated_results['party1__sum'] or 0
... # same for other fields

and for regions summary page:

region_summary = Results.objects.values('region_number').annotate(party1_sum=Sum('party1'), party2_sum=Sum('party2'), party3_sum=Sum('party3')).order_by()

, where .values(...).annotate(...).order_by() is translated into:

SELECT fields_in_values_plus_annotation FROM table_name GROUP BY fields_in_values ORDER BY NULL;
Charnel
  • 4,222
  • 2
  • 16
  • 28
  • Where do I put ```from django.db.models import Sum``` in ```models.py``` or ```views.py```? – Hardrocker Feb 27 '20 at 08:23
  • Well, better practices is to have a `manager.py` file where you add the functionality for default or custom model manager, but in the result you anyway need to call this methods in views in order to pass the result to template context, so the answer is - `views.py` – Charnel Feb 27 '20 at 08:28
  • Do I need to put this into a new function in ```views.py``` or put into the existing function? – Hardrocker Feb 27 '20 at 08:44
  • If you have an existing function you can put it there. – Charnel Feb 27 '20 at 08:48
  • I have an existing function ```def general_results(request): general_elections = GeneralElections.objects.all() context = { 'general_elections': general_elections, } return render(request, 'general.html', context)``` How do I write your code into this function? I keep getting an error on the server ```AttributeError: Manager isn't available; Results is abstract``` – Hardrocker Feb 27 '20 at 08:53
  • Did you made a model abstract? – Charnel Feb 27 '20 at 09:27
  • Yes, I made the base model abstract=True since I only needed tables for the two inherited models. Do I need to remove the abstract and have the base model create tables as well? – Hardrocker Feb 27 '20 at 09:36
  • You can't query an abstract table. The purpose of having abstract is inheritance. So, yes, you need to have a real model that may be inherited from the abstract one (or may not, if you do not need this) and query that model. – Charnel Feb 27 '20 at 10:20
  • I've been trying this for the last couple of hours without much success. Is it possible you can show me what the detailed code is in the answer? Sorry I don't mean to be a bother. – Hardrocker Feb 27 '20 at 18:21
  • The full code will be to long for posting it in comments. Try to create normal (not abstract) models, setup a view like [this](https://docs.djangoproject.com/en/3.0/ref/class-based-views/base/#django.views.generic.base.TemplateView) and put a query result into template context. – Charnel Feb 27 '20 at 20:03
  • Good news! After much effort I was finally able to get it working. :). I finally was able to fully understand your code and use it to get my desired results. One final question though. Can I use the same method to create a summary to display only the ```TOTAL``` for each party for both elections? Please see the last table above. I tried doing it but it didn't work. – Hardrocker Feb 28 '20 at 05:33