Skip to content

cannot add arguments to menus.  #145

Open
@tirohia

Description

@tirohia

Took me a bit, but I can create menus alright. Cannot for the life of me figure out how to dynamically allocate URLs to each of the menus/submenus. I have a list of cancerTypes that I have in the Django database. I am trying to use those to generate a series of sub-menus, one for each cancerType. I can create the menu entries but not link them to a page with a URL using reverse().

My menus.py looks like this:

from django.urls import reverse
from simple_menu import Menu, MenuItem
from hc.models import CancerType
from hc.views import CancerView, SampleView

level1Cancertypes = CancerType.objects.filter(parent__name="ZERO2")
level1 = []

for cancer_type in level1Cancertypes:
    menu_item = MenuItem(
        title=cancer_type.name,  # Use the name of the CancerType as the title of the menu item
        url=reverse("hc:cancer")
    )
    level1.append(menu_item)

Menu.add_item("main", MenuItem(title="All",
                               url=reverse("hc:cancer"),
                               weight=10,
                               children=level1
                               ))

Menu.add_item("main", MenuItem(title="Sample",
                               url=reverse("hc:sample"),
                               # url="/wibble",
                               weight=10,
                               ))

my urls.py looks like this:

from django.urls import path
from . import views

app_name = "hc"
urlpatterns = [
    path("", views.IndexView.as_view(), name="index"),
    path('cancer/', views.CancerView.as_view(), name="cancer"),
    path("sample/", views.SampleView.as_view(), name="sample"),
]

And the relevant part of my views.py looks like this:

from django.http import HttpResponse, HttpResponseRedirect
from django.shortcuts import get_object_or_404, render
from django.urls import reverse
from django.views import generic
from django.views.generic import ListView, TemplateView 
from .models import CancerType, Sample


class IndexView(generic.ListView):
    template_name = "hc/index.html"


class CancerView(TemplateView):
    template_name = 'hc/cancer.html'


class SampleView(TemplateView):
    template_name = 'hc/sample.html'

All of this I've tried to make as identical as possible to the code in the example4 here — urls.py, views.py and menus.py. This all works.

As soon as I try to pass an argument via kwargs, it falls over. Line 23 of menus.py suggests that I should be able to do something like this in my menus.py:

for cancer_type in level1Cancertypes:
    menu_item = MenuItem(
        title=cancer_type.name,
        url=reverse("hc:cancer", kwargs={'cancerId': 1})
    )

as long as I change the url pattern to be:

urlpatterns = [
    path("", views.IndexView.as_view(), name="index"),
    path('cancer/<int:cancerId>', views.CancerView.as_view(), name="cancer"),
    path("sample/", views.SampleView.as_view(), name="sample"),
]

The instant I do that, though, the app goes down with

Reverse for 'cancer' with no arguments not found. 1 pattern(s) tried: ['hc/cancer/(?P<cancerId>[0-9]+)\\Z']

There's nothing in the example views.py to suggest that I should be changing the number of parameters the view needs.

class SubPageView(TemplateView):
    template_name = 'accounts/subpage.html'

And if I manually enter the URL http://127.0.0.1:8000/hc/cancer/1/, I get a 404. I have checked, there is a cancer type with an id of 1.

Issues #70 and (possibly?) #83 might be suggesting that the reverse call in the menu item creation might be a problem due to being resolved too early or some such? Not sure if I'm following those right. Either way, the subclassing solution in #70 doesn't appear to work for me. Takes me right back to

django.urls.exceptions.NoReverseMatch: Reverse for 'cancer' not found. 'cancer' is not a valid view function or pattern name.

which is exceptionally frustrating when best I can tell from the Django documentation, using "name" in

path('cancer/<int:pk>', views.CancerView.as_view(), name="cancer")

should be sufficient to define a view called "cancer". In short, I have no idea what's happening there (day 2 of Django for me, which might have something to do with it)

Anyway. Any thoughts on what I'm doing would be much appreciated.
Thanks
Ben.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions