Issues with getting a No Reverse Match Error

HI working on a new site using Django. can’t seem to figure this bug out. First the intended site will be structured as;

Home page - Showing different languages with links to countries you can learn those languages in. Click on a country on home page → Country page Country page will list all fo the schools that teach that language in that country. Click on a school on country page → School page.

I figured out this line of code in the Country page is causing the issue, but I don’t know how to fix it

<a href="{% url 'schools' country_id=country.id schools_id=schools.id %}">
    <div class="left"><h4>Test Link</h4></div>
</a>

This is the error I get in the browser

NoReverseMatch at /5/ Reverse for ‘schools’ with arguments ‘(’’,)’ not found. 1 pattern(s) tried: [’(?P<country_id>[0-9]+)/(?P<schools_id>[0-9]+)/

Code from the project: Models.py

from django.db import models

class Languages(models.Model):
    language = models.CharField(max_length=100, blank=True, null=True)
    country = models.ManyToManyField('Country', blank=True)
    image = models.CharField(max_length=100, blank=True)

    def __str__(self):
        return self.language

class Country(models.Model):
    country_name = models.CharField(max_length=50)
    country_image = models.CharField(max_length=100, blank=True)
    country_city = models.ManyToManyField('City', blank=True)

    def __str__(self):
        return self.country_name

class City(models.Model):
    city_name = models.CharField(max_length=50)
    city_image = models.CharField(max_length=1000, blank=True)
    city_schools_in = models.ManyToManyField('Schools', blank=True)

    def __str__(self):
        return self.city_name

class Schools(models.Model):
    school_name = models.CharField(max_length=100)
    school_image = models.CharField(max_length=1000, blank=True)
    school_country = models.ManyToManyField('Country', blank=True)
    school_city = models.ManyToManyField('City', blank=True)
    school_description = models.TextField()
    school_accreditations = models.ManyToManyField('Accreditations', blank=True)
    school_lpw = models.IntegerField()
    school_cs = models.IntegerField()
    school_course = models.ManyToManyField('CoursePrices', blank=True)

    def __str__(self):
        return self.school_name

class Accreditations(models.Model):
    accreditation_name = models.CharField(max_length=50)

    def __str__(self):
        return self.accreditation_name

class CoursePrices(models.Model):
    course_title = models.CharField(max_length=50, blank=True)
    lessons_per_week = models.IntegerField()
    class_size = models.IntegerField()
    weekly_price =  models.IntegerField()
    language_level = models.CharField(max_length=50, blank=True)

    def __str__(self):
        return self.course_title

Views.py

from django.shortcuts import render
from django.http import Http404

from .models import Schools, CoursePrices, Languages, Country, City


def home(request):
    languages = Languages.objects.all()
    return render(request, 'home.html', {
        'languages': languages,
    })

def country(request, country_id):
    try:
        country = Country.objects.get(id=country_id)
    except Languages.DoesNotExist:
        raise Http404('Language not found')
    return render(request, 'country.html', {
        'country': country,
    })

def schools(request, country_id, schools_id):
    try:
        schools = Schools.objects.get(id=schools_id)
    except Schools.DoesNotExist:
        raise Http404('school not found')
    return render(request, 'schools.html', {
        'schools': schools,
    })

urls.py

from django.contrib import admin
from django.urls import path

from schools import views

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', views.home, name='home'),
    path('<int:country_id>/<int:schools_id>/', views.schools, name='schools'),
    path('<int:country_id>/', views.country, name='country'),

]

Any help would be greatly appreciated. Also please forgive any mistakes in posting or coding, still very new to coding/ life in general :slight_smile:

What view is generating the page that is throwing that error? I don’t see a view that you’ve provided containing both the country and school in the context.

Hi Ken, Thanks for the reply. The view would be this one.

def schools(request, country_id, schools_id):
    try:
        schools = Schools.objects.get(id=schools_id)
    except Schools.DoesNotExist:
        raise Http404('school not found')
    return render(request, 'schools.html', {
        'schools': schools,
    })

That looks like it would be the view that the bad link is supposed to send you to, not the view creating the page with the bad link - or am I missing something?

Actually, rereading your original post, I believe I’m looking for this one:

So the issue appears to be that you’re attempting to render this:

Which is referencing a variable in your context named “schools”, but your call to render in your view doesn’t include schools in your context.

Hi Ken, I think I understand what you are staying maybe I made a mistake in the implementation of the views.

So the home page has a list of all of the languages.
this is the view for it

def home(request):
    languages = Languages.objects.all()
    return render(request, 'home.html', {
        'languages': languages,
    })

and this is the link I’ve used on the home page to send the user to the country page
Home page link

<a href="{% url 'country' country_id=country.id %}">
	<div class="left"><h4>{{ country.country_name }}</h4></div>
</a>

Country page view (the view that should load)

def country(request, country_id):
    try:
        country = Country.objects.get(id=country_id)
    except Languages.DoesNotExist:
        raise Http404('Language not found')
    return render(request, 'country.html', {
        'country': country,
    })

when clicking on this link on the home page is when it throws an error, the error only shows when I have the link below (School page link) on the country page (without this link on the country page, the country page loads fine.

School page link

<a href="{% url 'schools' country_id=country.id schools_id=schools.id %}">
	<div class="left"><h4>Test Link</h4></div>
</a>

the above link is intended to load the individual schools page which would be this view

def schools(request, country_id, schools_id):
    try:
        schools = Schools.objects.get(id=schools_id)
    except Schools.DoesNotExist:
        raise Http404('school not found')
    return render(request, 'schools.html', {
        'schools': schools,
    })

I think I understand what is happening because I can access the schools page if I manually go to localhost 8000/6/2/ but I’m not sure how I would fix it. I think I could pass the schools id in to the country view but do I need to pass something to the render?

Example (something like this I would guess but can’t get it to work)

def country(request, country_id, schools_id):
    try:
        country = Country.objects.get(id=country_id)
        schools = Schools.objects.get(id=schools_id)
    except Languages.DoesNotExist:
        raise Http404('Language not found')
    return render(request, 'country.html', {
        'country': country, 'schools': schools,
    })

than what would be needed for the schools view. thanks

Your example is pretty much exactly what you need to do. But now you have the issue that your country view is expecting two parameters - country_id and school_id, but your home page link is only prepping 1 parameter, and your url for it is only expecting one.

Oh interesting. So have I made a mistake in the way I have implemented all of the views? seems like there would have been an easier way I’ve just missed it

Not all, but I think you may need a more “firm” idea of what each page is supposed to display and do.

My understanding of what I think you’re trying to achieve is:

  • Page 1
    • List of Countries, each one linking to page 2
  • Page 2
    • List of Schools within a country
      • Takes the country_id as a parameter from the link in page 1
      • Builds links for each school with the school_id and the country_id passed in as a parameter
  • Page 3
    • Details of a school
      • Takes the school_id as a parameter from the link in page 2
      • If you need to know which country you were looking at when this school was selected, then you would also need to pass in the country_id from the previous page.

Am I close?

Hi yep that pretty much it. only addition is that the schools are filtered by city on page 2 but that is done through the model ive created. I just can’t really figure out how to get there. :thinking:

Are the schools filtered by city on Page 2, or are they sorted/organized by city on that page? If they’re to be filtered, then you’re actually looking at adding another page to the sequence.
(Or, you can make this more “dynamic” by using JavaScript to manipulate data on the page without performing full page refreshes.)

Hi, yep sorted by city on the page then will be ‘dynamic’ though the use of JS