Link to detail view not working. (Reverse for '..' with arguments '('',)' not found. 1 pattern(s) tried: ['common/nut/(?P<pk>[0-9]+)/$'])

Hej!

I’m having trouble with my detail view. I want to link multiple DetailViews together but I can’t get to the right page or am get the error:
[Reverse for '..' with arguments '('',)' not found. 1 pattern(s) tried: ['common/nut/(?P<pk>[0-9]+)/$']](https://stackoverflow.com/questions/69613066/reverse-for-with-arguments-not-found-1-patterns-tried-common)

Via the url I can get to the right page so the view in my views.py is working correctly.

<!-- detail.html -->

<h3>Institution</h3>
    <p><b>Name: </b>{{institution.name}}</p>
    <p><b>Abbreviation: </b>{{institution.abbreviation}}</p>

    <p><b>Parent institution: </b>
        <a href="{% url 'stakeholders:institution_detail' institution.id %}">
            {{institution.parent_institution}}
        </a></p>

When I put it like that I only get linked to the exact same page. If I try {% url 'stakeholders:institution_detail' institution.parent_institution.id %} I get the above mentioned error message. But I can show the id like that! So this isn’t the problem either.
It should transfer to the DetailView of another institution.

Same problem with a link to different DetailView:

<!-- detail.html -->

<p><b>Address: </b>
    <b>NUTS (level 3): </b>
        <a href="{% url 'common:nuts_detail' nuts.id %}">
                {{institution.nuts_level_3}}
    </a>
</p>

if I put it like that the error message dissappeares but then nothing at all is shown.

{% for nuts in plant.nuts_level_3.all %}
    <a href="{% url 'common:nuts_detail' nuts.id %}">
        {{nuts.name_native}}
    </a>
{% endfor %}

Does anyone have an idea?
It seems as I am missing something.
Any help appreciated!

Best regards
piahh

I think that in order to provide any tangible guidance, we’d need to see the urls.py file for the definitions being used here, along with the models involved.

Everything works fine when I just put it in the url. I just can’t link it.

# stakeholders/urls.py

app_name = "stakeholders"
urlpatterns = [
    path("institutions", search_institution, name="institutions"),  # path to the institution query
    path("individuals", search_individuals, name="individuals-view"),  # path to the contact details query
    path("contact-notes", search_contact_notes, name="search_contact_notes"),  # path to the contact notes
    path("research", search_research_topics, name="research_topics"),  # path to the research need query
    path("institution/<int:pk>/", views.InstitutionDetail.as_view(), name="institution_detail"),
    path("individual/<int:pk>/", views.IndividualDetail.as_view(), name="individual_detail"),
    path("research/<int:pk>/", views.ResearchDetail.as_view(), name="research_detail"),
    path("project/<int:pk>/", views.ProjectDetail.as_view(), name="project_detail"),
    path("nace/<int:pk>/", views.NaceDetail.as_view(), name="nace_detail"),
    path("keyword/<int:pk>/", views.KeywordDetail.as_view(), name="keyword_detail"),
]
models.py

class Institution(models.Model):
    name = models.CharField(
        verbose_name=_("Name of the institution"),
        max_length=200,
    )
    abbreviation = models.CharField(  # null=False, but "" allowed. Is Django convention
        verbose_name=_("Acronym"),
        max_length=25,
        blank=True,
        help_text=_("if applicable"),
    )
    parent_institution = models.ForeignKey(
        "self",
        verbose_name=_("Parent institution"),
        on_delete=models.SET_NULL,
        blank=True,
        null=True,
        help_text=_("if applicable"),
    )
    nuts_level_3 = models.ForeignKey(
        NutsLevel3,
        on_delete=models.PROTECT,
        blank=True,
        null=True,
    )
    class Meta:
        verbose_name = _("Institution")
        verbose_name_plural = _("Institutions")

    def __str__(self):
        if self.abbreviation:
            return f"{self.name} ({self.abbreviation})"
        else:
            return f"{self.name}"


class NutsCountry(models.Model):
    code = models.CharField(max_length=2, unique=True)
    name_native = models.CharField(max_length=100, blank=True)

    def __str__(self):
        return f"{self.name_native}"


class NutsLevel1(models.Model):
    code = models.CharField(max_length=3, unique=True)
    nuts_country = models.ForeignKey(NutsCountry, on_delete=models.CASCADE)
    name_native = models.CharField(max_length=100, blank=True)

    def __str__(self):
        return f"{self.name_native}"

    def is_child_of(self, nuts_country):
        return self.nuts_country == nuts_country


class NutsLevel2(models.Model):
    code = models.CharField(max_length=4, unique=True)
    nuts_level_1 = models.ForeignKey(NutsLevel1, on_delete=models.CASCADE)
    name_native = models.CharField(max_length=100, blank=True)

    def __str__(self):
        return f"{self.name_native}"

    def is_child_of(self, nuts_any):
        return self.nuts_level_1 == nuts_any or self.nuts_level_1.is_child_of(nuts_any)


class NutsLevel3(models.Model):
    code = models.CharField(max_length=5, unique=True)
    nuts_level_2 = models.ForeignKey(NutsLevel2, on_delete=models.CASCADE)
    name_native = models.CharField(max_length=100, blank=True)

    def is_child_of(self, nuts_any):
        return self.nuts_level_2 == nuts_any or self.nuts_level_2.is_child_of(nuts_any)

    def __str__(self):
        return f"{self.name_native}"

    class Meta:
        verbose_name = _("Nuts Level 3")
        verbose_name_plural = _("Nuts Level 3's")

We may be looking at different issues for the different cases. To try and reduce the chance of confusion, I’m only going to address the first issue here at the moment.

Ok, so looking at the first case -

You’re saying that if you change this to:

    <p><b>Parent institution: </b>
        <a href="{% url 'stakeholders:institution_detail' institution.id %}">
            {{institution.parent_institution.id}}
        </a></p>

You get the numerical value displayed? (Yes, the link is wrong. I’m only asking for confirmation regarding the displayed text in this specific situation.)

(Side note: Since parent_institution is a nullable field, if you’re looking at an institution without a parent, this will generate the error being displayed.)

Yes. But I don’t know what’s wrong with the link. Can you help me figure it out?
And how can I add an if loop to only get the link/info when there is a parent?

The error message you posted in the title does not appear to be for this case. (The institution_detail link.) I am assuming that the actual error received in this case is referencing the url institution/(?P<pk>[0-9]+)/$ ?
If this is not the exact error that you are receiving for this, please post what you’re getting.

Is there more to this template than what you’ve shown here? (Is it possible that there’s another part of this template that is throwing the error?)

See the docs for the template if tag for details on using it.

Ahh yes. Sorry. Got the error message like you said. I have multiple apps with the same error and got the message wrong.

Reverse for 'institution_detail' with arguments '('',)' not found. 1 pattern(s) tried: ['stakeholders/institution/(?P<pk>[0-9]+)/$']

My template is rather long, therefor I decided to just show a snippet. My models are longer as well. But I only get the error there. Other parts are working fine.

When I get this part out of my code everything works.

Unfortunately, all I can say at this point is that if this fragment works:

(Meaning that you get an integer number showing up as the link with a different integer as the url within the href)

But this fragment throws an error:

    <p><b>Parent institution: </b>
        <a href="{% url 'stakeholders:institution_detail' institution.parent_institution.id %}">
            {{institution.parent_institution.id}}
        </a></p>

Then there’s something else happening outside of what you’re showing here. (It could be something as simple as a typo in your template that is throwing things off - but I can’t tell.)

Based upon what you’ve provided, this should work. Without a more complete picture of what’s going on, I’m not sure that there’s anything else I can do to help.

{% extends "landing/base.html" %}
{% load static %}
{% load i18n %}

{% block page-title %} {%translate "View Institutions Detail" %} {% endblock %}
{% block head %}
<link href="{% static 'landing/vendor/tabulator/dist/css/tabulator.min.css' %}" rel="stylesheet">
<link href="{% static 'landing/vendor/tabulator/dist/css/bootstrap/tabulator_bootstrap4.min.css' %}" rel="stylesheet">
{% endblock %}

{% block content %}

<h3>Institution</h3>

<p><b>Name: </b>{{institution.name}}</p>
<p><b>Abbreviation: </b>{{institution.abbreviation}}</p>


<p><b>Parent institution: </b>
    <a href="{% url 'stakeholders:institution_detail' institution.id %}">
        {{institution.parent_institution}}
    </a>
</p>


<h3>Contacts</h3>
<p><b>Contact notes: </b>{{institution.contact_notes}}</p>
<p><b>Internal contact: </b>{{institution.internal_contact_at_dbfz}}</p>


<p><b>Type of organisation: </b>
    <a href="{% url 'stakeholders:institutions' %}?type_of_organization={{institution.type_of_organization}}">
        {{institution.type_of_organization}}
    </a>
</p>


<p><b>Subtype of organisation: </b>
    <a href="{% url 'stakeholders:institutions' %}?subtype_of_organization={{institution.subtype_of_organization}}">
        {{institution.subtype_of_organization}}
    </a>
</p>


<p><b>NUTS level 3: </b>{{institution.nuts_level_3}} <i>(waiting for the plants app to generate a link)</i></p>


<h2>NACE categories</h2>

{% for nace in institution.nace_sections.all %}
<p><b>Nace sections: </b>
    {{nace.code}} -
    <a href="{% url 'stakeholders:nace_section_detail' nace.id %}">
        {{nace.description_english}}
    </a>
</p>
{% endfor %}


{% for nace in institution.nace_divisions.all %}
<p><b>Nace divisions: </b>
    {{nace.code}} -
    <a href="{% url 'stakeholders:nace_division_detail' nace.id %}">
        {{nace.description_english}}
    </a>
</p>
{% endfor %}


{% for nace in institution.nace_groups.all %}
<p><b>Nace groups: </b>
    {{nace.code}} -
        <a href="{% url 'stakeholders:nace_group_detail' nace.id %}">
            {{nace.description_english}}
        </a>
</p>
{% endfor %}


{% for nace in institution.nace_classes.all %}
<p><b>Nace classes: </b>{{nace.code}} -
    <a href="{% url 'stakeholders:nace_class_detail' nace.id %}">
        {{nace.description_english}}
    </a>
</p>
{% endfor %}


<h2>Address</h2>
<p>{{institution.street}} {{institution.house_number}}</p>
<p>{{institution.add_to_address}}</p>
<p>{{institution.postal_code}} {{institution.city}}</p>
<p>{{institution.country}}</p>

<p><b>Geo latitude: </b>{{institution.geo_latitude}}</p>
<p><b>Geo longitude: </b>{{institution.geo_longitude}}</p>
<p><b>Quality level coordinates: </b>{{institution.quality_level_coordinates}}</p>

<h2>Additional Information</h2>
<p>{{institution.website}}</p>

<p><b>Partner in DBFZ project: </b></p>
{% for project in institution.partner_in_dbfz_projects.all %}
    <p><a href="{% url 'stakeholders:project_detail' project.id %}">{{project.id_project_database}}</a>
        - {{project.vorhabentitel}}
    </p><br/>
{% endfor %}


<p><b>Data used in DBFZ project: </b></p>
{% for project in institution.data_used_in_dbfz_projects.all %}
    <p><a href="{% url 'stakeholders:project_detail' project.id %}">{{project.id_project_database}}</a>
        - {{project.vorhabentitel}}
    </p><br/>
{% endfor %}


<p>
<h2>Keywords and used data</h2>
{% for word in institution.keywords.all %}
    <li>
        <a href="{% url 'stakeholders:keyword_detail' word.id %}">
            {{ word.keyword_english }} / {{word.keyword_german}}
        </a>
    </li>
{% endfor %}
</p>


<p><b>Number of employees: </b><br/>
    {% for employee in institution.number_of_employees.all %}
        <a href="{% url 'stakeholders:individuals-view' %}?member_in_institution={{institution.id}}">
        {{employee.year}} - {{employee.number_of_employees}} ({{employee.source}})
    </a>
    {% endfor %}
</p>



<p><b>Status of institution: </b><br/>
    {% for status in institution.status_of_institution.all %}
        {{status.year_valid_from}}-{{status.year_valid_to}}
        <b>
            {{status.status}}
        </b>
        ({{status.year_decision}}-{{status.month_decision}})<br/>
    {% endfor %}
</p>


<h2>Additional</h2>

<a class="btn btn-sm btn-info" href="{% url 'stakeholders:institutions' %}?parent_institution={{institution.id}}">All institutions with {{institution.name}} as parent</a></td>

<p></p>


{% endblock %}

This is my whole template.
I can’t find anything but it is definitely not redirecting me to the right DetailView but always to the ‘old’ one.

# views.py

class InstitutionDetail(DetailView):
    model = Institution

    def get(self, request, *args, **kwargs):
        institution = get_object_or_404(Institution, pk=kwargs['pk'])
        context = {'institution': institution}
        return render(request, 'stakeholders/institution_detail.html', context)

@login_required
def search_institution(request):
    institutions = Institution.objects.all()

    myFilter = InstitutionFilter(request.GET, queryset=institutions)
    institutions = myFilter.qs

    context = {"institutions": institutions, "myFilter": myFilter}

    return render(request, 'stakeholders/search_table_institutions.html', context)

Correct. That’s what this fragment is supposed to do.

So if you replace it with:

<p><b>Parent institution: </b>
    <a href="{% url 'stakeholders:institution_detail' institution.parent_institution.id %}">
        {{institution.parent_institution}}
    </a>
</p>

This should create the link to the parent, if the current institution has a parent assigned.
And it’s this change that is causing the error to be thrown?

Yes, this gives me the error. And there IS a parent. I double checked it again.

Unfortunately, I can’t recreate the behavior you’re describing.

I’ve modeled an example similar to your code and the url tag is functioning exactly as expected.

In case there’s something interfering with the normal sequence of events, you could try this:

(Note the use of the underscore between “institution” and “id” instead of a period.)

Ok, I see another potential issue.

I didn’t catch that you were overriding one of the system-supplied generic class-based views.

Try:

class InstitutionDetail(DetailView):
    model = Institution
    template_name =  'stakeholders/institution_detail.html'

(Yes, that’s the complete view I would like for you to try.)

You’re actually fighting the generic view here. It will create a context entry by the name of the class being viewed. You don’t need to override get.

1 Like

I tried the new view and the _id in the template and still get the NoReverseMatch error :confused:

How odd that it does work in your code and not in mine.
Could there be something with my model and the way the data lies in the database? The model is aswell longer than the part I posted (didn’t want the question to get too confusing with code). I do have a lot in my models and my templates.

Either way many thanks for your time and help!

It’s something. Whether it’s the model, view, template, a custom model manager, other utility code, third-party library, whatever - I can’t tell from what you’ve provided. About all I can say is that the problem is not “here” (meaning the code that you have posted so far).

One “brute force” solution available at this point would be to override the get_context_data method in your view, and manually add the parent object to the context directly. But in the long-run I think you’d probably be better served by finding the actual root cause of this issue because it’s likely to affect something else down the road.

This is my whole module. I can’t figure out what could cause this problem, but I will try to set up a test module with not that much content and check if that will link the right detail view.

class Institution(models.Model):
    class QualityLevelCoordinatesChoices(models.TextChoices):
        NO_ENTRY = "no_entry", _("no entry")
        UNCHECKED = "unchecked", _("unchecked")
        PRELIMINARILY_CHECKED = "preliminarily_checked", _("preliminarily checked")
        CHECKED = "checked", _("checked")

    class TypeChoices(models.TextChoices):
        # TODO explanations missing
        HES = "HES", _("secondary and higher education establishment")
        OTH = "OTH", _("other entity")
        PRC = "PRC", _("private for profit company")
        PUB = "PUB", _("public body, excluding research and education")
        REC = "REC", _("research organisation, excluding education")
        UNKNOWN = "unk", _("unknown")

    class SubtypeChoices(models.TextChoices):
        SME = "SME", _("micro, small and medium-sized enterprise")
        LRE = "LRE", _("large enterprise")
        UNKNOWN = "unk", _("unknown size")

    name = models.CharField(
        verbose_name=_("Name of the institution"),
        max_length=200,
    )
    abbreviation = models.CharField(  # null=False, but "" allowed. Is Django convention
        verbose_name=_("Acronym"),
        max_length=25,
        blank=True,
        help_text=_("if applicable"),
    )
    parent_institution = models.ForeignKey(
        "self",
        verbose_name=_("Parent institution"),
        on_delete=models.SET_NULL,
        blank=True,
        null=True,
        help_text=_("if applicable"),
    )
    street = models.CharField(
        verbose_name=_("Street of head office"),
        max_length=150,
        blank=True,
    )
    add_to_address = models.CharField(
        verbose_name=_("Extra address information"),
        max_length=150,
        blank=True,
    )
    house_number = models.CharField(
        verbose_name=_("House number"),
        max_length=12,
        blank=True,
    )
    postal_code = models.CharField(
        verbose_name=_("Postal code"),
        max_length=12,
        blank=True,
    )
    city = models.CharField(
        verbose_name=_("City"),
        max_length=100,
        blank=True,
    )
    country = models.CharField(
        verbose_name=_("Country"),
        max_length=150,
        blank=True,
    )
    geo_latitude = models.DecimalField(
        max_digits=11, decimal_places=6, blank=True, null=True
    )
    geo_longitude = models.DecimalField(
        max_digits=11, decimal_places=6, blank=True, null=True
    )
    quality_level_coordinates = models.CharField(
        max_length=30,
        verbose_name="Quality of the coordinates",
        choices=QualityLevelCoordinatesChoices.choices,
        default=QualityLevelCoordinatesChoices.NO_ENTRY,
    )
    website = models.URLField(
        verbose_name=_("Main website"),
        max_length=200,
        blank=True,
    )
    legal_form = models.CharField(
        verbose_name=_("Legal form"),
        max_length=100,
        blank=True,
    )
    type_of_organization = models.CharField(
        max_length=3,
        choices=TypeChoices.choices,
        default=TypeChoices.UNKNOWN,
    )
    subtype_of_organization = models.CharField(
        max_length=3, choices=SubtypeChoices.choices, blank=True
    )
    contact_notes = models.TextField(
        verbose_name=_("Notes about contacting this institution"),
        blank=True,
        max_length=1000,
    )
    internal_contact_at_dbfz = models.CharField(
        verbose_name=_("Internal contact"),
        max_length=500,
        blank=True,
        help_text=_("Ask this employee at DBFZ how to contact this institution."),
    )
    nuts_level_3 = models.ForeignKey(
        NutsLevel3,
        on_delete=models.PROTECT,
        blank=True,
        null=True,
    )
    # Django makes ManyToMany relationships unique by default (that means DBFZ can't be in 'A' two times)
    nace_sections = models.ManyToManyField(NaceSection, related_name="nace_sections")
    nace_divisions = models.ManyToManyField(NaceDivision, blank=True)
    nace_groups = models.ManyToManyField(NaceGroup, blank=True)
    nace_classes = models.ManyToManyField(NaceClass, blank=True)

    keywords = models.ManyToManyField(Keyword, blank=True)
    data_used_in_dbfz_projects = (
        models.ManyToManyField(  # stakeholders_institution_data_used_in_dbfz_projects
            DbfzProject,
            related_name="used_data_of_institutions",
            blank=True,  # DBFZProject.used_data_of_institutions
        )
    )
    partner_in_dbfz_projects = models.ManyToManyField(
        DbfzProject,
        related_name="partner_institutions",
        blank=True,  # DBFZProject.partner_institutions
    )

    class Meta:
        verbose_name = _("Institution")
        verbose_name_plural = _("Institutions")

    def __str__(self):
        if self.abbreviation:
            return f"{self.name} ({self.abbreviation})"
        else:
            return f"{self.name}"

    # TODO translate validation error
    def clean(self):
        if self.subtype_of_organization:
            if self.type_of_organization != self.TypeChoices.PRC:
                raise ValidationError(
                    f'Subtype of organization may only be set if type of organization is "{self.TypeChoices.PRC.label}"'
                )
        if (
                self.type_of_organization == self.TypeChoices.PRC
                and not self.subtype_of_organization
        ):
            raise ValidationError(
                f'If type of organization is "{self.TypeChoices.PRC.label}" please also set subtype of organization'
            )

Just out of curiosity, what database engine are you using here?

Can you verify at the database level that your institution table has a field named parent_institution_id? That it is type integer? (Or at least the same data type as the primary key of the table.)

yes, there is a parent_institution_id with an integer type. The only difference is that it is nullable.

An mssql database. I could check if I can get a different engine and see if it’s working there.

That’s your call, obviously. I was asking because I wanted to see if I could replicate it with the same database engine you’re using. (Sorry, I don’t have an mssql up and running on any of my test environments.)

Another thing to check is if this happens with all foreign keys or just these few.

2 Likes