Django URL with parameter not working with include - django

I am trying to pass a parameter to a url before my include statement. I think my problem should be similar to this one, but I can't figure out why mine isn't working. I get the error NoReverseMatch at /womens/ Reverse for 'shampoo' with arguments '('womens',)' not found. 1 pattern(s) tried: ['(?P<gender>womens|mens)/items/shampoo/$']
*config.urls*
urlpatterns = [
re_path(r'(?P<gender>womens|mens)/items/$, include('items.urls')),
...
]
*items.urls*
urlpatterns = [
path('shampoo', views.shampoo, name='shampoo'),
path('soap', views.soap, name='soap'),
...
]
{% url 'items:shampoo' gender='male' %}
I expect to get male/items/shampoo, but it doesn't work. Despite this, I can still manually go to male/items/shampoo.

This might work when you do it manually like male/items/shampoo, but as it is giving a NoReverseMatch error, Django is not able to find a matching URL pattern that you provided which included the parameters.
After looking into this for some time, something like this might be happening when you use {% url 'items:shampoo' gender='male' %}
Assuming you are running this on your localhost, you expect the URL to look like male/items/shampoo
This url says, look into male section, among items show shampoo.
But you are passing the parameter in the wrong place. {% url 'items:shampoo' gender='male' %} means that the parameter male is passed to a url which has a namespace of shampoo. The URL with the namespace of shampoo does not accept any parameters.
Maybe try changing your code as follows.
*config.urls*
urlpatterns = [
re_path(r'^$', include('items.urls')),
...
]
from django.conf.urls import url, path
*items.urls*
urlpatterns = [
url(r'^(?P<gender>\w+)/items/shampoo/$', views.shampoo, name='shampoo'),
path('soap', views.soap, name='soap'),
...
]

Related

How to get URL without required parameters

I have the following path in my URLS:
path('remove_order/<int:order_id>', RemoveOrder.as_view(), name='md_remove_order')
What I would like to do is get the URL WITHOUT specifying an order_id in my template. Like this:
{% url 'md_remove_order' %}
so it gives me something like this:
"remove_order/"
I will then pass this value to my Javascript where the order_id will be added dynamically.
You can use re_path
re_path('remove_order(?:/(?P<pk>[0-9]+))?/$', RemoveOrder.as_view(),name='md_remove_order')
So it will both work for remove_order/ and remove_order/123/
An easy way to do that is to create another url that points to the same view but without the parameter:
urlpatterns = [
path('remove_order/<int:order_id>', RemoveOrder.as_view(), name='md_remove_order'),
path('remove_order/', RemoveOrder.as_view(), name='md_remove_order_without_params'),
]
Then use that new url
{% url 'md_remove_order_without_params' %}

Django urls page not found

In my urls.py I include my urls for each app, for example;
from app.insight import urls as insight_urls
urlpatterns = [
path('insight/', include(insight_urls), name='insight')
]
In insight.urls I include the view and the url like this:
urlpatterns = [
path('create/', InsightAddView.as_view(), name='create-insight')
]
The error I get says:
Page not found. No insight found matching the query
However, when I change the create-insight url from create/ to create/new/ it works.
Why doesn't the create/ url work?
Thanks to #cagrias I solved the problem. I had another url matching the create/ url. This one:
path('<slug:slug>/', InsightView.as_view(), name='read-insight-slug')
I solved it by changing that one to:
path('read/<slug:slug>/', InsightView.as_view(), name='read-insight-slug'),

NoReverseMatch when trying to access view from template

I am getting a NoReverseMatch error for the following:
Hello
Where I passed a string fileids from my view to my template when rendering.
Reverse for 'generateCSV' with arguments '()' and keyword arguments
'{'file_ids': '11111111_22222222'}' not found. 1 pattern(s) tried:
['mainapp/secondaryapp/generateCSV/(?P[\d{8,20}]+\_*)/$']
My mainapp/urls.py is:
from django.conf.urls import url, include
from mainapp import views
urlpatterns = [
...
url(r'^secondaryapp/', include('secondaryapp.urls', namespace="secondaryapp")),
]
and secondaryapp/urls.py is:
from django.conf.urls import url
from search import views
urlpatterns = [
url(r'^$', views.secondaryapp.as_view(), name='secondaryapp'),
url(r'^generateCSV/(?P<file_ids>[\d{8,20}]+\_*)/$', views.generateCSV, name='generateCSV'),
]
generateCSV is a functional view, and secondaryapp is the name of the class-based view. I am rendering the template within the class based view, and attempting to call the functional view with the parameter fileids.
If I simply hard-code the url as follows:
<a href = "generateCSV/{{fileids}}/">
Everything works as expected.
Thanks very much for your time reading and for any help you can give me!
A friend of mine pointed out that my regex was wrong; if you use the following in secondaryapp/urls.py
url(r'^generateCSV/(?P<fileids>(?:\d{8,20}_)*\d{8,20}?)/$', views.generateCSV, name='generateCSV'),
with the following in secondaryapp/templates/secondaryapp/template.html
<a href = "{% url 'mainapp:secondaryapp:generateCSV' fileids %}">
then things work as expected.
Apparently, it was the square brackets that did me in when attempting to use them for grouping with special characters; according to him, they turn what are normally operators into regular characters, and potentially caused me to accept commas and braces as well.
According to this:
"Within square brackets, most characters are interpreted literally."

Build-in views?

I installed a module to Django and this module has ceertain views within itself. Also it comes with a demo to see the features. I am looking at the code from the demo for a while now but I cant figure out how a template is rendered over the build in views.
The module i'm working with is swingtime:
Here is an example:
Excerpt from the template:
<a class="plain" href="{% url 'swingtime-daily-view' prev_day.year prev_day.month prev_day.day %}">
URL Directory
urlpatterns = [
url(r'^$', TemplateView.as_view(template_name='intro.html'), name='demo-home'),
url(r'^karate/', include('karate.urls')),
url(r'^admin/', include(admin.site.urls)),
url(r'^docs/?$', RedirectView.as_view(url='/docs/index.html', permanent=True)),
url(r'^docs/(?P<path>.*)$', serve, dict(document_root=doc_root, show_indexes=False))
]
So the url must somehow link to a built-in template i suppose?
When I try to implement similar code in my project the url can not be reversed?
And also: How would one edit the template for such a build in view?
Thank you!
Check the urls.py file in the karate module. you will find the url there.
It will be something like
urlpatterns = [
...
url(r'daily-view', view='view_name' name='swingtime-daily-view'),
...
]
Now the name argument of the url is the important thing you're looking for as I don't know the actual path or view set there.
So when you have something like this
<a class="plain" href="{% url 'swingtime-daily-view' prev_day.year prev_day.month prev_day.day %}">
The url dispatcher will look through the app urls for the url with this view....this is called named url patterns.
Read more on how url patterns work URL DISPATCHER IN DJANGO

How to use namespace urls with django in a reusuable app

I have a django app, a forum app, that has templates with it. In those templates, there are urls that point to parts of the app. For instance the thread_list template has links to each thread like so:
{% for thread in threads %}
{{thread.title}}
{% endfor %}
The thing is, I don't really like calling my urls "forum_thread". I prefer just "thread" and using the namespace feature of django. "forum_thread" may be used somewhere else in the project (namespace collision).So it will look like this:
{% for thread in threads %}
{{thread.title}}
{% endfor %}
but this doesn't feel like the correct way to do this. The docs are kind of unclear here.
I want this app to be reusable and easy to configure. But I also want to use the best standards. I don't want to have the to make the user specify their own namespace name, and then have them edit every single url in each template.
How should I do urls in this app?
From what I can gather you should be able use {% url forum:thread thread %} as you've described. Namespaces always seem to be defined with two variables, namespace and app_name.
If you then do the following in urls.py:
url(r'^/forum/', include('forum.urls', namespace='forum', app_name='forum')),
url(r'^/foo/', include('forum.urls', namespace='foo', app_name='forum')),
url(r'^/bar/', include('forum.urls', namespace='bar', app_name='forum')),
In my understanding, this defines 3 instances of the app 'forum', 'foo', 'bar', and the default (which has namespace==app_name).
When you reverse forum:thread, it uses the current context to determine which one to use- if you are in namespace 'foo' it will use that, otherwise it will fall back on the default.
If anyone is able to clarify how Django decides what the 'current' namespace/app is that would be very helpful. I currently categorise it as 'black magic'.
Some clarification on the actual difference between namespace and app_name would also be helpful- it's possible that I have this totally reversed. The current docs are highly ambiguous.
Note: I have this working for initial requests, but I'm currently unable to make this work for AJAX requests- those always use the default instance for some reason.
This might be a simple syntax error. I was following the Django Tutorial, and I changed mysite/urls.py improperly. The original syntax:
url(r'^polls/', include('polls.urls')),
The desired change:
url(r'^polls/', include('polls.urls', namespace="polls")),
What I did:
url(r'^polls/', include('polls.urls'), namespace="polls"),
Correcting the syntax resolved the issue.
based on my understanding of this question:
in Django 2.1.7
You can app name in app's urls.py file
# app's urls.py
from django.urls import path
from . import views
app_name = 'forum'
urlpatterns = [
path('thread/', views.mark_done, name='thread')
]
in main urls.py
# urls.py
....
urlpatterns = [
path('forum/', include('forum.urls')),
]
then you can employ {% url 'forum:thread' %} in your template
If you wanna use it in a for loop
I think we should
create a view return all threads as context
then add a path to that view
...
path('thread/<int:pk>', views.mark_done, name='thread')
the url in template will like:
{% for thread in threads %}
{{thread.title}}
{% endfor %}