简体   繁体   中英

How to get JavaScript to recognize a context_dict object from views.py in Django

I've taken over a Django project from a former co-worker and I've got to edit his code to add a line to a Google Viz line chart.

Since the line chart already exist I'm trying to follow the logic used to create it as much as possible (given that I've never done anything like this before). I added the new data model to models.py , successfully migrated it, and found the part of views.py where he set up the data for the line chart and a table below it.

I tried to copy what he did in views.py and then the code seems to pick up from there in a JavaScript file where the chart is actually created. However when I get to JavaScript it seems to recognize his object from views.py but not mine, based on what I've seen in the Web Console log.

His key object created in views.py was module_progressjs . My object with the data for the new line is called tii_progressjs . It looks to me like a dictionary called context_dict is used to pass the data from Python to JavaScript, but I copied this approach and it didn't seem to work.

Here is the heart of the views.py code. Everything relating to the word "module" is the original (working) code and everything relating to "tii" or "turn it in" is the part I've added. Some of this code block may relate to the table rather than the chart, but I wasn't sure yet, so I followed the logic for all of it, even though I'll only edit the chart:

try:
    module_attempts = Studentmoduleprogress.objects.values().filter(Person_bnrid = Person_bnrid).annotate(Max('Start_date')).order_by('-Start_date')
    turn_it_in = TII.objects.values().filter(Person_bnr_id = Person_bnrid).annotate(Max('Course_start')).order_by('-Course_start')
    context_dict['turn_it_in'] = turn_it_in
    context_dict['module_attempts'] = module_attempts
    tiiavg = TII.objects.values('COURSE_IDENTIFICATION','Course_start').annotate(wk1_avg=Avg('TurnItIn_W01'), wk2_avg=Avg('TurnItIn_W02'),
                                                                                        wk3_avg=Avg('TurnItIn_W03'),wk4_avg=Avg('TurnItIn_W04'),
                                                                                        wk5_avg=Avg('TurnItIn_W05'),wk6_avg=Avg('TurnItIn_W06'),
                                                                                        wk7_avg=Avg('TurnItIn_W07'),wk8_avg=Avg('TurnItIn_W08'),
                                                                                        wk9_avg=Avg('TurnItIn_W09'),wk10_avg=Avg('TurnItIn_W10'),
                                                                                        wk11_avg=Avg('TurnItIn_W11'),wk12_avg=Avg('TurnItIn_W12'))

    modavg = Studentmoduleprogress.objects.values('Module_code','Start_date').annotate(wk1_avg=Avg('Week_01'), wk2_avg=Avg('Week_02'),
                                                                                        wk3_avg=Avg('Week_03'),wk4_avg=Avg('Week_04'),
                                                                                        wk5_avg=Avg('Week_05'),wk6_avg=Avg('Week_06'),
                                                                                        wk7_avg=Avg('Week_07'),wk8_avg=Avg('Week_08'),
                                                                                        wk9_avg=Avg('Week_09'),wk10_avg=Avg('Week_10'),
                                                                                        wk11_avg=Avg('Week_11'),wk12_avg=Avg('Week_12'))

    #print modavg
    context_dict['tiiavg'] = mark_safe(json.dumps(list(tiiavg), cls = DateTimeEncoder))
    context_dict['modavg'] = mark_safe(json.dumps(list(modavg), cls = DateTimeEncoder))
    module_progress = []
    for module in module_attempts:
        max_week = module['Module_duration_max']
        progress_lst = ['Module_code', module['Module_code'], 'Start_date', module['Start_date'], 'End_date', module['End_date']]
        for wk in range(1, max_week + 1):
            week = 'Week_' + (str(wk) if wk >= 10 else '0' + str(wk))
            progress_lst.append(week)
            progress_lst.append(module[week])
        module_progress.append(progress_lst)

    tii_progress = []
    for module in turn_it_in:
        max_week = module['Module_duration_max']
        progress_lst = ['COURSE_IDENTIFICATION', module['COURSE_IDENTIFICATION'], 'Course_start', module['Course_start'], 'Course_end', module['Course_end']]
        for wk in range(1, max_week + 1):
            week = 'TurnItIn_W' + (str(wk) if wk >= 10 else '0' + str(wk))
            progress_lst.append(week)
            progress_lst.append(module[week])
        tii_progress.append(progress_lst)

    #print module_progress
    context_dict['tii_progress'] = tii_progress
    context_dict['module_progress'] = module_progress
    context_dict['module_progressjs'] = mark_safe(json.dumps(module_progress, cls = DateTimeEncoder))
    context_dict['tii_progressjs'] = mark_safe(json.dumps(tii_progress, cls = DateTimeEncoder))

The JS is as follows. I have cut out the first 95% of it for brevity, but if you'd like to see the complete script please check the edit history:

   // Module Progress
    google.charts.setOnLoadCallback(drawModProgress);

    $(window).resize(function(){
        //google.charts.setOnLoadCallback(drawModProgress);
        drawModProgress();
    });


    function drawModProgress() {

        var data = new google.visualization.DataTable();
        var selOption  = $("#mcode option:selected").val();
        var dateOption  = $("#sdate option:selected").val();
        var modset = {};
        var selModule = [];
        var selTII= [];
        var wks = [];
        var posts = [];
        var yTicks = [];
        var l=0, m=0;    
        var tii = [];


        for(i=0; i < module_progressjs.length; i++)
        {
            if(module_progressjs[i][1] == selOption)
            //if (modset.Module_code == selOption && modset.Start_date == dateOption)
            {

                selModule[0]= module_progressjs[i];
                //console.log(selModule[0]);

           }        
        }
       //console.log(tii_progressjs[1]);
       //console.log(tii_progressjs);
        /*for(ii=0; ii < tii_progressjs.length; ii++)
        {
            if(tii_progressjs[ii][1] == selOption)
            {

                selTII[0]= tii_progressjs[ii];
           }        
        }*/

If I uncomment the code referring to my tii_progressjs object then the code breaks. When I look in the log his object has data but mine isn't there.

Not sure if this matters but the HTML is:

{% if module_progress %}

<div class="row">
    <div class="col-lg-12 col-md-12">
    <h3 class="sp-font-bl"> <i class="fa fa-book sp-icon-module" aria-hidden="true"></i> Modules Progression</h3>

        <div class="panel panel-default">
            <div class="panel-body">
                <label id="sp-modsel">Module Code</label>
                <select id="mcode" class="selectpicker" >   
                    {% for mod in module_attempts %} 

                        <option value="{{ mod.Module_code }}"> {{ mod.Module_code }} </option>

                    {% endfor %}    

                </select>


                <div class="container-fluid ">
                    <div class="row" > 
                        <div class="col-xs-12 col-md-12">                         
                            <div id="module_progress" ></div>
                        </div>
                    </div>
                </div>

                <div class="table-responsive">
                    {% if module_attempts %}                    
                      <table id="modules" class="table table-striped table-bordered table-hover">
                        <thead align="center">
                            <tr class="sp-td-bg01">
                                <th>Module Code</th>  
                                <th>Module Name</th>      
                                <th>Start Date</th>
                                <th>End Date</th>
                                <th>Module Grade</th>
                            </tr>
                        </thead>
                        <tbody>                     
                            {% for module in module_attempts %}
                              <tr>
                                <td scope="row"> {{module.Module_code}} </td>
                                <td> {{module.Module_name}} </td>
                                <td> {{module.Start_date}} </td>
                                <td> {{module.End_date}} </td>
                                <td> {{module.Module_grade}} </td>
                              </tr>
                            {% endfor %}                      
                        </tbody>
                      </table>
                    {% endif %}               
                </div>          

UPDATE: I am starting to think that the missing link is the HTML. It sounds like the document.getelementbyid statement in the JS is pulling info from the HTML DOM and I haven't adding anything to the HTML.

UPDATE 2: Look at this bit at the end of the HTML template, I bet I should edit this:

<script type="text/javascript"> 
var studtests = {{ studtests | safe }};
var studobjs =  {{ studobjs | safe }};
//var modulesjs =  {{ modulesjs | safe }};
var studsumryjs = {{ studsumryjs | safe }};
var module_progressjs = {{ module_progressjs | safe }};
var modavg = {{ modavg | safe }};
</script>

<script src = "{%static 'js/student.js' %}" type="text/javascript"> 
</script>
{% endblock %} 

The answer seems to be that you don't go directly from views.py to JS, but rather from views.py to your HTML template, and then pass data to JS when you invoke the script.

Specifically, I had to change the following code block in the HTML:

<script type="text/javascript"> 
var studtests = {{ studtests | safe }};
var studobjs =  {{ studobjs | safe }};
var studsumryjs = {{ studsumryjs | safe }};
var module_progressjs = {{ module_progressjs | safe }};
var modavg = {{ modavg | safe }};
</script>

<script src = "{%static 'js/student.js' %}" type="text/javascript"> 
</script>

to

<script type="text/javascript"> 
var studtests = {{ studtests | safe }};
var studobjs =  {{ studobjs | safe }};
var studsumryjs = {{ studsumryjs | safe }};
var module_progressjs = {{ module_progressjs | safe }};
var modavg = {{ modavg | safe }};
var tiiavg = {{ tiiavg | safe }};
var tii_progressjs = {{tii_progressjs | safe}};
</script>

<script src = "{%static 'js/student.js' %}" type="text/javascript"> 
</script>

Then I was able to make the necessary changes to the JS to include the extra line I wanted in the chart.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM