Django=3.0.8
urls.py
urlpatterns += [
path('<slug:categories>/', include('categories.urls', namespace="categories")),
]
categories/urls.py
urlpatterns = [
path('', CategoryGeneralView.as_view(), name='general'),
re_path(r'^(?P<type>novosti|tema)$/',CategorySpecialView.as_view(), name="type"),
path('draft/<slug:slug>/', PostDetailView.as_view(), name="draft_post_detail"),
path('<slug:slug>/', PostDetailView.as_view(), name="post_detail"),
]
Problem
When I input either of
http://localhost:8000/windows/tema/
http://localhost:8000/windows/novosti/
the request goes to PostDetailView. But I want it to go to CategorySpecialView.
How can I achieve this?
Why not just use 2 separate paths, i.e.:
path('novosti/', CategorySpecialView.as_view(), name = 'type'),
path('tema/', CategorySpecialView.as_view(), name = 'type'),
Related
I have two django apps with URLs
app_name = 'app1'
urlpatterns = [
path('url1/', ..., name='name1')
path('<slug:username>/', ..., name='name2')
]
and
app_name = 'app2'
urlpatterns = [
path('url2/', ..., name='name3')
path('<slug:username>/action2/', ..., name='name4')
]
This would not work if I include them in the master urlpatterns as
urlpatterns = [
path('', include('app1.urls'),
path('', include('app2.urls'),
]
because url2/ would first match <slug:username>/ and trigger an error for unknown username.
There are a few potential solutions but none works very well for me:
Use non-slug url2 such as ~url2. That means all urls in app2 has to start with something like ~ or ^.
Redefine some URLs in the master urlpatterns but then I will have to import views from the apps and remove urls from the app urlpattern.
Use regular expression to explicitly exclude some names from the <slug:username>. This could work but then any changes in app2 urlpatterns need to be reflected in app1's <slug:username> ... exclude certain names.
It is possible to do something like
urlpatterns = [
path('', include('app1.urls'), # non-user part
path('', include('app2.urls'), # non-user part
path('', include('app1.urls'), # user part
path('', include('app2.urls'), # user part
]
so that fixed-name URLs will be matched before <slug:username>?
From Django docs:
include((pattern_list, app_namespace), namespace=None)
Parameters:
pattern_list – Iterable of path() and/or re_path() instances.
app_namespace (str) – Application namespace for the URL entries being
included
You can include specific urls with this method:
urlpatterns = [
path('', include(([path('url1/', <YourViewName>)], 'app1'))),
path('', include(([path('url2/', <YourViewName>)], 'app2'))),
path('', include(([path('<slug:username>/', <YourViewName>)], 'app1'))),
path('', include(([path('<slug:username>/action2/', < YourViewName >)], 'app2'))),
]
First element of tuple inside include is the list of path/re_path instances that you want to include, and the second one is the app name.
I'm trying to learn Django and I'm following Corey Shafer's tutorials (https://www.youtube.com/watch?v=a48xeeo5Vnk), but when I try to make two different pages, I get automatically directed to the one with an "empty address":
In his:
/Blog
/urls.py
it looks like this:
from django.conf.urls import path
from . import views
urlpatterns = [
path('', views.home, name='blog-home'),
path('about/', views.about, name='blog-about'),
]
and when he goes to localhost:8000/blog/about, the page displays correctly
When I try to imitate his code for blog/urls.py:
from django.conf.urls import url
from . import views
urlpatterns = [
url(r'', views.home, name='blog-home'),
url(r'^about/', views.about, name='blog-about'),
]
the result of the localhost:8000/blog/about is the content of views.home, and not views.about.
The following works correctly, when I write a name instead of an empty string:
urlpatterns = [
url(r'^home', views.home, name='blog-home'),
url(r'^about/', views.about, name='blog-about'),
]
But I don't understand why it worked in a previous version, why it won't work now, and what could fix it
A url matches if it can find a substring that matches, the empty string r'' thus matches every string.
You should make use of anchors to specify the start (^) and end ($) of the string:
urlpatterns = [
# ↓ ↓ anchors
url(r'^/$', views.home, name='blog-home'),
url(r'^about/', views.about, name='blog-about'),
]
Note: As of django-3.1, url(…) [Django-doc] is
deprecated in favor of re_path(…) [Django-doc].
Furthermore a new syntax for paths has been introduced with path converters: you
use path(…) [Django-doc] for that.
I always get this error "The empty path didn't match any of these." When I try to access the page through this url:
url('^about/$',views.AboutView.as_view(),name = 'about')
and when I remove "^about/$" part, then it works:
url('',views.AboutView.as_view(),name = 'about')
How could I resolve it?
This is link for call:
<li><a class="navbar-brand" href="{% url 'about'%}">About</a></li>
this is view.py
class AboutView(TemplateView):
template_name = 'about.html'
and, this urlpatterns
urlpatterns = [
url('^about/$',views.AboutView.as_view(),name = 'about')
]
from django.conf.urls import url
from blog import views
urlpatterns = [ url('about',views.AboutView.as_view(),name='about') ]
instead of this
from django.urls import path
from blog import views
urlpatterns = [
path('about/', views.AboutView.as_view(),name='about'),
use this pattern same as your main url
path('about/', views.AboutView, name='about'),
It's not good to follow 2 ways of creating urls, Since django==2.0 they have introduced very nice and easy way to declare urls.
In the old way...
from django.conf.urls import url
urlpatterns = [
url(r'^about/$', AboutView.as_view(), name="about")
]
But In the new way it's lot more cleaner...
from django.urls import path
urlpatterns = [
path('about/', view.AboutView.as_view())
]
But if you want to stick with the regular expressions, Use re_path() instead of path().
urlpatterns = [
re_path(r'about/$', view.AboutView.as_view())
]
In my it's better stay with one pattern, old or new but not both. It makes your code look more cleaner.
I have the following in my root URLconf module (there's more, but not important, so left out):
urlpatterns = [
re_path(r'^password-reset-redirect-view/(?P<uidb64>[0-9A-Za-z_\-]+)/(?P<token>[0-9A-Za-z]{1,13}-[0-9A-Za-z]{1,20})/$',
password_reset_redirect,
name = 'password_reset_confirm'),
path('', include('search.urls')),
path('', include('customer_portal.urls')),
path('rest-auth/', include('rest_auth.urls')),
path('rest-auth/registration/', include('rest_auth.registration.urls')),
Here's the customer_portal.urls:
urlpatterns = [
path('customer/contact/', views.contact),
path('', views.home),
re_path(r"^confirm-email/(?P<key>[-:\w]+)/$", views.email_verification,
name="account_confirm_email"),
]
Here's the rest_auth.registration.urls:
urlpatterns = [
url(r'^$', RegisterView.as_view(), name='rest_register'),
url(r'^verify-email/$', VerifyEmailView.as_view(), name='rest_verify_email'),
url(r'^account-confirm-email/(?P<key>[-:\w]+)/$', TemplateView.as_view(),
name='account_confirm_email'),
]
As you can see both included urls.py urlpatterns have a view named 'account_confirm_email'.
Somewhere in the code this is ran:
url = reverse(
"account_confirm_email",
args=[emailconfirmation.key])
Since customer_portal.urls is included before rest_auth.registration.urls, I expect the route account_confirm_email in customer_portal.urls to be returned by the above reverse method. But instead I get the rest_auth.registration.urls route URL.
Just to be sure I commented out the route in rest_auth.registration.urls, and then I did get the correct URL (customer_portal URL) returned.
It is filled into an email, I check that email and see that I have the wanted url: http://127.0.0.1:8000/confirm-email/......./, instead of: http://127.0.0.1:8000/rest-auth/registration/account-confirm-email/...../
Can anyone tell me why the customer_portal URL isn't the one being reversed in both cases?
Django docs say:
Django runs through each URL pattern, in order, and stops at the first one that matches the requested URL.
I'm using Django 1.8 and I can't figure out why one particular url isn't getting matched.
The url is /weapons. Django is adding a trailing slash to it which I believe is because of the APPEND_SLASH option being true by default. Even if I try to reach the url without the slash it will fail then try the slash.
This is the error I get:
top level urls.py
urlpatterns = [
url (r'^admin/', include (admin.site.urls)),
url (r'^', include ('core.urls', namespace = 'core')),
url (r'^', include ('equipment.urls', namespace = 'equipment')),
]
core urls.py
urlpatterns = patterns [
url (r'^$', views.index, name = 'index'),
]
equipment urls.py
urlpatterns = [
url (r'^equipment$', views.index, {'type':'index'}, name = 'index'),
url (r'^weapons$', views.index, {'type':'weapons'}, name = 'weapons'),
url (r'^armor$', views.index, {'type':'armor'}, name = 'armor'),
url (r'^accessories$', views.index, {'type':'accessories'}, name = 'accessories'),
]
I would do:
urlpatterns = [
url (r'^admin/', include (admin.site.urls)),
url (r'^home/', include ('core.urls', namespace = 'core')),
url (r'^equipment/', include ('equipment.urls', namespace = 'equipment')),
]
and
urlpatterns = [
url (r'^weapons/$', views.index, {'type':'weapons'}, name = 'weapons'),
]
note the [] instead of patterns in django 1.8
your url would look like:
http://localhost:1000/equipment/weapons/
which makes sense right?
Try to remove leading ^ from urls in core/urls.py and equipment/urls.py.
Turns out it was a caching issue. I tried it using Ctrl + F5 but it didn't work so I tried the page in Incognito mode which worked. So I used the Developer Tools to reload the page and now it works.