Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

How can I pass a Django url parameter to template's url method?

I have this urls.py file:

...

urlpatterns = [
    path('region_service_cost/<str:region>/', views.region_service_cost, name='region_service_cost'),
    path('monthly-region-service-cost/<str:region>/', views.monthly_region_service_cost, name='monthly-region-service-cost')
]

And I have this views.py file:

# Create your views here.
from django.shortcuts import render
from django.http import JsonResponse
from .models import MonthlyRegionServiceCost

def region_service_cost(request, region):
    return render(request, 'region-service-cost.html')

def monthly_region_service_cost(request, region='global'):
    colors = ['#DFFF00', '#FFBF00', '#FF7F50', '#DE3163', '#9FE2BF', '#40E0D0', '#6495ED', '#CCCCFF', '#9CC2BF',
              '#40E011', '#641111', '#CCCC00']
    labels = [ym['year_month'] for ym in MonthlyRegionServiceCost.objects.values('year_month').distinct()][:12]
    datasets = []

    for ym in labels:
        for i, obj in enumerate(MonthlyRegionServiceCost.objects.filter(region=region, year_month=ym)):
            dataset = {
               'label': obj.service,
               'backgroundColor': colors[i % len(colors)],
               'data': [c.cost for c in MonthlyRegionServiceCost.objects.filter(service=obj.service, region=region)]
            }
            datasets.append(dataset)


    return JsonResponse(data={
        'labels': labels,
        'datasets': datasets
    })

and here is my region-service-cost.html file:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

{% extends 'base.html' %}

{% block content %}

  <div id="container" style="width: 75%;">
    <canvas id="monthly-region-service-cost" data-url="{% url 'monthly-region-service-cost' region=region %}/{{ region | urlencode }}/"></canvas>

  </div>

  <script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>

  <script>

    $(function () {

      var $productCostChart = $("#monthly-region-service-cost");
      $.ajax({
        url: $productCostChart.data("url"),
        success: function (data) {
          console.log(data);

          var ctx = $productCostChart[0].getContext("2d");

          new Chart(ctx, {
            type: 'bar',
            data: { labels: data.labels, datasets: data.datasets, },
            options: {
                plugins: { title: { display: true, text: 'Stacked Bar chart for pollution status' }, },
                scales: { x: { stacked: true, }, y: { stacked: true } }
            }
          });

        }
      });

    });

  </script>

{% endblock %}

When I point my browser to http://127.0.0.1:8000/region_service_cost/global/ I get this output:

NoReverseMatch at /region_service_cost/global/
Reverse for 'monthly-region-service-cost' with keyword arguments '{'region': ''}' not found. 1 pattern(s) tried: ['monthly\\-region\\-service\\-cost/(?P<region>[^/]+)/\\Z']
Request Method: GET
Request URL:    http://127.0.0.1:8000/region_service_cost/global/
Django Version: 4.2.10
Exception Type: NoReverseMatch
Exception Value:    
Reverse for 'monthly-region-service-cost' with keyword arguments '{'region': ''}' not found. 1 pattern(s) tried: ['monthly\\-region\\-service\\-cost/(?P<region>[^/]+)/\\Z']
Exception Location: /Users/russell.cecala/COST_REPORTS/django/cost_explorer/venv/lib/python3.9/site-packages/django/urls/resolvers.py, line 828, in _reverse_with_prefix
Raised during:  monthly_cost.views.region_service_cost
Python Executable:  /Users/russell.cecala/COST_REPORTS/django/cost_explorer/venv/bin/python
Python Version: 3.9.6

>Solution :

Replace your views.py‘s region_service_cost() function with this:

def region_service_cost(request, region):
    return render(request, 'region-service-cost.html', {
        "region": region
    })

The problem with your code was that you had not passed the region to your HTML page, so it did not know what region meant in this line:

<canvas id="monthly-region-service-cost" data-url="{% url 'monthly-region-service-cost' region=region %}/{{ region | urlencode }}/"></canvas>

This solution will work for any region, including global.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading