Multiple detail pages according to relations


I have many to many related models. Type and Country.

class Type(models.Model):
    name = models.CharField(max_length=100)

class Country(models.Model):
    name = models.CharField(max_length=100)
    slug = models.SlugField(blank=True, unique=True)
    types = models.ManyToManyField("Type", related_name="countries")

    def get_absolute_url(self):
        return reverse('country', kwargs={'slug':self.slug})

I will have a list of the countries related to types. I want to create separate detail pages for each type.
Also, I need to have an actual detail page of countries.

When I click country under the different type, the detail page should be different.

  • Countries: France, England, Canada …
  • Types: Appetizer, Soup & Salad, Main Course, Dessert …

For example;

  • Appetizer in France, ------------->(Template I)
  • Soup and Salad in France --------->(Template I)
  • Dessert in France ---------------->(Template I)
  • And France ----------------------->(Template II)

I am sharing the design with you to visualize what I have.

How can I achieve this and which structure I need to build?
I’m waiting for your ideas and help.


If I understand what you’re looking for, I believe it’s an issue of laying out the URL structure for what you want for each page, and generating those URLs as the appropriate links.

For example, you could define a url like:
which would invoke a view passing it two parameters - the PK for the country and the type for that country to determine the details being presented.

Your view can then use that type parameter to do whatever needs to be done for that type.

If you need a view for just a country, in the absence of a type, you could define a url like:
to request a different view that will only display the basic Country information.

@KenWhitesell, thank you for the answer and interest.

The part I couldn’t figure out is that,
How can I pass the different URLs dynamically in the template ?
As you see in the design(the image I upload), the same country-related different types and take a part singularly.

Currently, I’m using a slug to pass the country detail view.
urlpatterns = [
    path(countries/', views.CountryListView.as_view(), name='countries'),
    path(country/<slug:slug>/', views.CountryDetailView.as_view(), name='country'),


class CountryListView(ListView):
    model = Country
    template_name = 'countries.html'

class CountryDetailView(DetailView):
    model = Country
    template_name = 'country_detail.html'


{% for country in object_list %}
    <li><a href="{{ country.get_absolute_url }}">{{ }}</a></li>
{% endfor %}


{% for type in types %}
   {% for country in type.countries.all %}

	a href="{{country.’get_related_url???’ }}">{{ }}</a>

    {% endfor %}
{% endfor %}

I try to show you the full path without details.
That’s why I used two for loop inside for loop and limited some detail.

You already have seen that what I need to reach in the design.

Can I achieve the structure I need,

if I adapt the URL arrangement you said to my URL management (slugs and get_absolute_url)

I’m not sure I’m understanding you here, but fortunately, I think it’s just a terminology issue.

First, I wouldn’t use “get_absolute_url” for a “details view” page. See the full docs section of get_absolute_url. My opinion is that you’re better off using either the reverse utility method in the view to select the url to be constructed, or the url template tag in your templates to perform the same work.

For example, lets say you have the following entries in your file:

path('/country/<int:pk>/<int:type>/', views.CountryTypeView.as_view(), name='country_type')
path('/country/<int:pk>/', views.CountryDetailView.as_view(), name='country')

Then, in your template you can construct the link as something similar to:
<a href="{% url 'country_type' %}">{{ }} in {{ }}</a>
<a href="{% url 'country' %}">{{ }} details</a>

I will arrange my code according to your answer. I think it is going to solve my issue.

I will share again after completion.