Nesting multiple 'for' loops

Question!

I am using Django 1.8.3 and Python 3.4.3

My application is starting to get large and I have several 'for' loops to access several objects within the same model. Although I am new to Python, I am guessing there is a more streamline way of preparing my code. Please see a small snippet below. The model is 'day_of_week' yet I have a 'for' loop for several objects. I also placed a snippet of the template code for a complete picture. Thank you for your help.

views.py

def get_context_data(self, **kwargs):
        context = super(EmailListView, self).get_context_data(**kwargs)
        days = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday']
        months = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October',
                  'November', 'December']
        subject_type = ['Offer', 'Sell', 'Fear', 'Learn']
        content_type = ['Offer', 'Sell', 'Fear', 'Learn']
        email_list = ['FMGB', 'FMGR', 'AE', 'IBA']

        total_campaigns = {}
        total_campaigns_month = {}
        total_recipients = {}
        total_unsubscribes = {}
        total_bounces = {}
        total_open = {}
        total_clicks = {}

        for day in days:
            total_campaigns[day] = Email.objects.filter(day_of_week=day).count()
        for recipients in days:
            total_recipients[recipients] = Email.objects.filter(day_of_week=recipients).aggregate(
                Sum('recipients')).get('recipients__sum', 0.00)
        for unsubscribes in days:
            total_unsubscribes[unsubscribes] = Email.objects.filter(day_of_week=unsubscribes).aggregate(
                Sum('unsubscribes')).get('unsubscribes__sum', 0.00)
        for bounces in days:
            total_bounces[bounces] = Email.objects.filter(day_of_week=bounces).aggregate(Sum('bounces')).get(
                'bounces__sum', 0.00)
        for open in days:
            total_open[open] = Email.objects.filter(day_of_week=open).aggregate(
                Sum('open')).get('open__sum', 0.00)
        for clicks in days:
            total_clicks[clicks] = Email.objects.filter(day_of_week=clicks).aggregate(
                Sum('clicks')).get('clicks__sum', 0.00)

Template Snippet... (email.html)

{% if email_list %}
    <tr>
       <td>Monday</td>
       <td>{{ total_campaigns.Monday }}</td>
       <td>{{ total_recipients.Monday }}</td>
       <td>{{ total_unsubscribes.Monday  }}</td>
       <td>{{ total_bounces.Monday  }}</td>
       <td>{{ total_open.Monday  }}</td>
       <td>{{ total_clicks.Monday  }}</td>
       <td>{% average total_open.Monday total_recipients.Monday %}</td>
       <td>{% average total_clicks.Monday total_open.Monday %}</td>
    </tr>
    ...


Answers

So I'm not totally sure if this is all correct syntax, but perhaps you might try this approach?

def initialize_dict(dict, days, dict_name):
    for day in days:
        if dict_name='':
            dict[day] = Email.objects.filter(day_of_week=day).count()
        else:
            dict[day] = Email.objects.filter(day_of_week=day)
                       .aggregate(Sum(dict_name))
                       .get(dict_name   '__sum', 0.00)

I'm not sure whether this is a better solution, but it is an alternative. You could decide to make the days a global variable instead of having to pass it into the function. A couple of sample calls would be:

initialize_dict(total_campaigns, days, '')
initialize_dict(total_recipients, days, 'recipients')

and so on... I hope this helps. Please feel free to critique this solution on why it is either a good or bad approach! I am still learning and improving myself :)



This video can help you solving your question :)
By: admin