0

I have a django view that returns this dictionary

args={'Residential': 'N/A', 'School': ('481 address', 600), 'Park': 'N/A', 'Religious': 'N/A', 'Childcare': ('123 address', 5)}

I have this code that correctly displays it on the HTML page

<h5><b>Nearest Childcare Parcel</b> = {{ Childcare }}</h5>
<h5><b>Nearest Park Parcel</b> = {{ Park }}</h5>
<h5><b>Nearest Religious Parcel</b> = {{ Religious }}</h5>
<h5><b>Nearest Residential Parcel</b> = {{ Residential }}</h5>
<h5><b>Nearest School Parcel</b> = {{ School }}</h5>

this outputs

enter image description here

which is okay but its ugly and messy.

I want to nicely put it into a table.

So here is my html code using the django jinja template

<div class="container">
      <h2>Property Search Results</h2>
      <table class="table">
        <thead>
          <tr>
            <th>Layer</th>
            <th>Address</th>
            <th>Distance to Property</th>
          </tr>
        </thead>

        <tbody>            
          <tr>
            {% if args %}
            <td>Childcare</td>            
            <td>{ args['Childcare'][0] }</td>
            <td>{ args['Childcare'][1] }</td>
            {% endif %}

          </tr>      
          <tr class="success">
            {% if args %}
            <td>Park</td>
            <td>{ args['Park'][0] }</td>
            <td>{ args['Park'][1] }</td>
            {% endif %}
          </tr>
          <tr class="danger">
            {% if args %}
            <td>Religious</td>
            <td>{ args['Religious'][0] }</td>
            <td>{ args['Religious'][1] }</td>
            {% endif %}
          </tr>
          <tr class="info">
            {% if args %}
            <td>Residential</td>
            <td>{ args['Residential'][0] }</td>
            <td>{ args['Residential'][1] }</td>
            {% endif %}
          </tr>
          <tr class="warning">
            {% if args %}
            <td>School</td>
            <td>{ args['School'][0] }</td>
            <td>{ args['School'][1] }</td>
            {% endif %}
          </tr>

        </tbody>
      </table>
    </div>

there are no errors but nothing gets displayed at all on the table.

What is the best way to get this too work? should I do a for loop through the args dictionary?

this is the entire view

class HomePageView(TemplateView):
    template_name = 'index.html'
    def get(self, request):
        cur = conn.cursor()
        cur.execute("delete from reporter_post")
        form = HomeForm()
        #posts = Post.objects.all()

        #args = {'form': form, 'posts': posts}
        return render(request, self.template_name, {'form': form})

    def post(self, request):
        form = HomeForm(request.POST)
        print(form)
        if form.is_valid():
            cur = conn.cursor()
            cur.execute("delete from reporter_post")
            form.save()
            g = geocoder.bing(str(form.cleaned_data['address']), key=bingkey)
            try:
              x,y=g.latlng[1],g.latlng[0]
              print(x,y)
              pre_qry='''with a as(select parcelid,owner_name,geom
                              from macomb_parcels_zoning_mun mpzu 
                              where st_intersects(geom,st_transform(st_setsrid(ST_FlipCoordinates(st_makepoint({0}, {1})),4326),102690))
                              )
                      update reporter_post set parcelid=a.parcelid, owner_name=a.owner_name,geom=a.geom from a;
                      '''.format(y,x)
              cur.execute(pre_qry)
              conn.commit()
              qry = '''                                    
                      with address1 as(select '{0}'::text subject_parcel_address, mpzu.*
                              from macomb_parcels_zoning_mun mpzu 
                              where st_intersects(geom,st_transform(st_setsrid(ST_FlipCoordinates(st_makepoint({1}, {2})),4326),102690))
                               ),
                      process 
                        as(select distinct on(zone_from_parcels,subject_parcel_address) zone_from_parcels,subject_parcel_address,buffered_parcel_address,owner_name,dist
                              from(select aa.address buffered_parcel_address,aa.owner_name,aa.zone_for_buff zone_from_parcels,
                                  round(st_distance(aa.geom,t.geom)::numeric,2 ) dist, t.subject_parcel_address
                                      from mac_parcels_union aa
                                      cross join lateral (
                                          select m.geom,m.subject_parcel_address, mbu.geom geom_buff 
                                          from address1 m join mac_buffer_union mbu on st_dwithin(m.geom,mbu.geom,2000)
                                              where mbu.parcelid = aa.parcelid and aa.parcelid <> m.parcelid 
                                          )t
                                  group by buffered_parcel_address,owner_name,zone_from_parcels,dist,subject_parcel_address
                                  order by dist) t
                          order by subject_parcel_address,zone_from_parcels,dist
                          )
                    SELECT zone_from_parcels zone_,subject_parcel_address,buffered_parcel_address,owner_name,dist::integer 
                                FROM process
                          '''.format(str(form.cleaned_data['address']), y, x)
              cur.execute(qry)
              row=cur.fetchall()
              print(row)
              if not row:
                  return render(request, self.template_name, {'form': form,'text': 'N/A'})
              else:
                  zones={'Childcare': 'N/A', 'School': 'N/A', 'Park': 'N/A', 'Residential': 'N/A', 'Religious': 'N/A'}
                  for x in row:
                      for k, v in zones.items():
                          if x[0] == k:
                              print(k, x[0])
                              zones[k] = x[2], x[4]


                  args = {'form': form, 'Residential': zones['Residential'],
                          'School': zones['School'], 'Religious': zones['Religious'],
                          'Childcare': zones['Childcare'], 'Park': zones['Park']}
                  return render(request, self.template_name, args)
                  print args
            except:
              args={'Residential': 'N/A', 'School': ('481 address', 600), 'Park': 'N/A', 'Religious': 'N/A', 'Childcare': ('123 address', 5)}
              return render(request, self.template_name, args)
ziggy
  • 1,488
  • 5
  • 23
  • 51
  • Please show the view function. I suspect `args` is not a context variable sent to the template. – Robin Zigmond Mar 04 '19 at 19:35
  • its hard coded for test purposes – ziggy Mar 04 '19 at 19:37
  • That's fine, we just need to see the view function, otherwise we don't know how what variables the template is receiving, and what their values are. (I have a suspicion, based on my reading of your post, that your `args` is a dictionary of all the variables, which you are supplying in the `render_template` call, which doesn't make `args` itself usable in the template. But I can't know for sure without seeing the view.) – Robin Zigmond Mar 04 '19 at 19:40
  • okay its very large but will post – ziggy Mar 04 '19 at 19:41
  • Thanks - so it's exactly as I suspected. You send the `args` dict to the template, but `"arts"` is not a key in it. So just check the appropriate variable for each row: `{% if Childcare %}` and so on. – Robin Zigmond Mar 04 '19 at 19:48
  • ohhh okay so then how do I get the value then? – ziggy Mar 04 '19 at 19:50
  • like what do I put in the `{{ Childcare[0] }}` ? this gives an error – ziggy Mar 04 '19 at 19:52
  • I am looking at this post https://stackoverflow.com/questions/8018973/how-to-iterate-through-dictionary-in-a-dictionary-in-django-template?rq=1 what would be my `data.items`, `args.items` ?? – ziggy Mar 04 '19 at 19:59
  • Are you definitely using Jinja? I know you mention it in your title, but in case you're not and using the default Django template engine, it needs to be `Childcare.0` etc. (I'm not as familiar with Jinja, but it seems the square bracket notation should work for that.) – Robin Zigmond Mar 04 '19 at 20:04
  • i think you are right, it seems to be the default template - this is my 1st project in django so excuse my inexperience with this. Childcare.0 works. write up a little answer with your recs and I will accept it – ziggy Mar 04 '19 at 20:07
  • Thanks, I will a bit later, am typing comments quickly on my phone while doing other things, which isn't the best circumstances to write up an answer. Happy to help though, and glad you got it sorted. – Robin Zigmond Mar 04 '19 at 20:19

1 Answers1

0

The problem is that in this code:

args = {'form': form, 'Residential': zones['Residential'],
        'School': zones['School'], 'Religious': zones['Religious'],
        'Childcare': zones['Childcare'], 'Park': zones['Park']}
return render(request, self.template_name, args)

there is no variable called args being passed to the template. The variables available in the template are precisely the keys of the dictionary which you've here called args - so form, School, Religious, Childcare and Park. The template knows nothing of the variable name you chose to use for the dictionary itself (indeed it's not unusual to pass a dictionary literal here, with no variable name at all - although it's perfectly legitimate to put it into a variable if it's more convenient).

So the conditions {% if args %} were always being interpreted as False, because args does not exist as far as the template is concerned.

And there is a further error, that in the Django template language, unlike in Python itself, all property access of any kind is done via dot notation, never with square brackets. So Childcare[0] won't work at all - you need to do Childcare.0 instead.

There is plenty of information about the Django template language in the official documentation.

Robin Zigmond
  • 17,805
  • 2
  • 23
  • 34