Django URL without trailing slash not working - python

This is a silly problem. I just created a project and have been trying to figure out this problem.
from django.conf.urls import url
from django.views.generic import TemplateView
urlpatterns = [
url(r'^$', TemplateView.as_view(template_name="index.html")),
url(r'^about$', TemplateView.as_view(template_name="about.html")),
url(r'^contact$', TemplateView.as_view(template_name="contact.html"), name="contact"),
url(r'^test$', TemplateView.as_view(template_name="test_start"), name="test_start"),
url(r'^test/sample$', TemplateView.as_view(template_name="test_start"), name="test_start"),
]
is included into
from django.conf.urls import url, include
from django.contrib import admin
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^', include('frontend.urls'))
]
When I go to localhost:8000/about, I get redirected to localhost:8000/about/ and there I get 404 Not Found.
UPDATE: I added more URLs into my URLconf.
UPDATE 2: I meant to not include trailing slashes. My apologies.
UPDATE 3: I opened the same URL in Firefox and the URL works like I intend. Could this be a problem with redirection and browser cache?

Did you enable the append_slash setting ?
https://docs.djangoproject.com/en/dev/ref/settings/#append-slash
using this may help to make it more explicit and is recommended throughout the django tutorials
url(r'^about/$', TemplateView.as_view(template_name="about.html")),
EDIT:
Deactivate the APPEND_SLASH settings (False) and use
url(r'^about$', TemplateView.as_view(template_name="about.html")),

First, I found out that Chrome automatically adds trailing slash at the end of the URL
Trailing URL Slashes in Django
So if you don't have a trailing slash on your URLS, a 404 redirect will show if you're using Chrome, but not if, say, Firefox.
Then from the comment of knbk from here,
How Django adds trailing slash
I made sure I had the CommonMiddleware class in setting.py and added 'APPEND_SLASH = False'
Then, cleared Chrome's cache, and problem solved!

You can just remove the $ from your regex, this indicates the end of line
url(r'^about', TemplateView.as_view(template_name="about.html")),
You could also just include a slash to your regex, since Django has a APPEND_SLASH setting which will issue a redirect
url(r'^about/$', TemplateView.as_view(template_name="about.html")),
if the request URL does not match any of the patterns in the URLconf and it doesn’t end in a slash, an HTTP redirect is issued to the same URL with a slash appended.

Change your url pattern for "about" to:
url(r'^about/?$', TemplateView.as_view(template_name="about.html")),
Without the /?, the regex ^about$ matches a string containing exactly the word "about".

Related

What the meaning of ^ for url

It might be too simple question.
I have this urlpatterns in urls.py
urlpatterns = [
url(r'^s3direct/', include('s3direct.urls')),
path('admin/', admin.site.urls),
]
localhost/admin works, but localhost/s3direct shows the 404 error.
Page not found (404)
Request Method: GET
Request URL: http://localhost:8099/s3direct
Using the URLconf defined in djang_test.urls, Django tried these URL patterns, in this order:
^s3direct/
admin/
The current path, s3direct, didn’t match any of these.
(I use runserver at port 8099)
The ^ in this case is a Regex-specific operator, meaning that it only matches the beginning of the string.
I believe that your problem is that you actually need to request http://localhost:8099/s3direct/ -- You're missing the trailing backslash

Resolving Django URLs with many trailing slashes - development vs. production inconsistency

I have a Python+Django website working under control of uWSGI and NginX.
On the production environment, each of the addresses below directs to an article. APPEND_SLASH=True setting makes the first URL (non-slash) redirect to the second URL (with one slash) - this is the part which I understand.
What is making third, fourth and every each URL with any number of slashes working?
1. http://example.com/my-article-slug
2. http://example.com/my-article-slug/
3. http://example.com/my-article-slug//
4. http://example.com/my-article-slug///
5. ...
URLs with many slashes just resolve the Django View (ArticleDetail) properly and show the article, without redirect (!).
However, on the Django local development web server, only first two of above links works. Http404 is returned if URL has more than one slash.
The DEBUG setting has nothing to do with this issue, according to my investigation.
It is worth noting that this behavior is a problem when I want to resolve a Django View from an URI, because addresses with many trailing slashes work correctly (on the production), but they are not resolved correctly by django.urls.resolve:
>>> from django.urls import resolve
>>> resolve('/my-article-slug/')
ResolverMatch(func=articles.views.ArticleDetail, args=(), kwargs={'slug': 'my-article-slug'}...
>>> resolve('/my-article-slug//')
django.urls.exceptions.Resolver404...
Django URLs cofiguration:
# urls.py
from django.urls import include, path
urlpatterns = [
path('', include('articles.urls')),
]
# articles/urls.py
from django.urls import path
from articles.views import ArticleDetail
urlpatterns = [
...
path('<slug:slug>/', ArticleDetail.as_view(), name='article-detail'),
...
]
By the way, I've noticed that it is quite common behavior, i.e.:
https://www.djangoproject.com////////////
https://docs.djangoproject.com/en/3.0////////////
https://www.dropbox.com////////////
https://www.dropbox.com/individual////////////
https://www.quora.com////////////
https://www.quora.com/answer////////////
Perhaps is it NginX-related issue?

Django URL give me space between root and included urls

So I create an url in root/project/urls.py with this lines
from django.conf.urls import include
from django.contrib import admin
from django.urls import path
urlpatterns = [
path('admin/', admin.site.urls),
path('users/', include('app.urls'))
]
while in my root/app/urls.py
from django.urls import path
from .views import UserView, AuthenticationView
urlpatterns = [
path('register/', UserView.as_view()),
path('auth/', AuthenticationView.as_view()),
]
So it is expected to give me http://localhost:8000/users/register and http://localhost:8000/users/auth urls.
Meanwhile my request doesn't behave as expected.
apparently it returns me a space between the root path and include path. I check my root/project/settings.py file I don't find any weird settings. Does anybody know what is going on?
The space is just for displaying how the URL is built up, on the debug screen only.
I have experienced the same and at first I too thought Django somehow added the space. In the end it really is that there is no match between the URL's specified and the URL in your browser. Safari doesn't display the full url, so error can happen quickly...
Some additional info on urls in Django can be found here.
The error message in your screenshot states that the request URL is http://localhost:8000/users does not exist.
Here you redirects /users/ to app.urls:
path('users/', include('app.urls'))
But in app.urls, you never included a pattern for when the URL ends with only "/users/". Instead, "/users/register/" and "/users/auth/" are both specified.
urlpatterns = [
path('register/', UserView.as_view()),
path('auth/', AuthenticationView.as_view()),
]
So http://localhost:8000/users/register and http://localhost:8000/users/auth should be valid URLs, but http://localhost:8000/users is not.
You can add another URL pattern for when the URL ends at "/users/":
urlpatterns = [
path('', AuthenticationView.as_view()), # maybe the same as /auth/ ?
path('register/', UserView.as_view()),
path('auth/', AuthenticationView.as_view()),
]
In conclusion, Django's actually not wrong about that page does not exist (404), it's because you hadn't match http://localhost:8000/users in any of the urlpatterns.
Have you tried to use regular expressions?
path(r'^admin/', admin.site.urls)
Otherwise in the Django 2 version the urls schema has been changed, I use url function instead the path function, that can be a possible fix for your problem

Django-nested-admin urls not loading

I'm trying to get any sort of nested inline to work with python 3 and django 1.8.
I tried django super-inlines and that didn't really make them nested, they just kinda showed up next to eachother.
I'm currently trying django-nested-admin and I get a page not found error with this pattern search:
^ ^$ [name='browse']
^admin/ ^server-data.js$ [name='nesting_server_data']
browse links to a separate set of urls and this just will not load any admin links.
urls.py:
from django.conf.urls import include, url
import nested_admin
urlpatterns = [
url(r'^', include('flightdb.urls')),
url(r'^admin/', include('nested_admin.urls')),
]
Connecting to /admin/ gets a 404 not found error.
Any help with why the page isn't loading or any better way to get nested-inlines to work would be greatly appreciated.
The pattern r'^' will match anything that also matches r'^admin/'. Django performs the URL matching by starting from the beginning of urlpatterns and progresses until it finds the first match. So in this case things that were supposed to be in admin are matching '^' which is flightdb.urls where they won't be found. You could potentially fix this issue by reordering the url's as follows:
urlpatterns = [
url(r'^admin/', include('nested_admin.urls')),
url(r'^', include('flightdb.urls')),
]
Now admin is checked for a match before the rest of the top level urls.
EDIT: I suspect your issues are coming from using "admin" in your url pattern to go to somewhere other than the default Django admin package. I did some searching around in the source of django-nested-admin and in particular came across something here:
https://github.com/theatlantic/django-nested-admin/blob/master/nested_admin/options.py in particular have a look at line 275:
context = {
'title': _('Add %s') % force_unicode(opts.verbose_name),
'adminform': adminForm,
'is_popup': (IS_POPUP_VAR in request.POST or
IS_POPUP_VAR in request.GET),
'show_delete': False,
'media': mark_safe(media),
'inline_admin_formsets': inline_admin_formsets,
'errors': helpers.AdminErrorList(form, formsets),
'root_path': reverse('admin:index'),
'app_label': opts.app_label,
}
Here there is a call to reverse('admin:index'). This needs to resolve to the usual admin path in order to work. When you have your url's defined like you do you run into the problem of admin now being something other than the default that django-nested-admin is expecting to see.
Perhaps try a different url pattern that is not "admin" such as the one suggested by their documentation:
url(r'^nested_admin/', include('nested_admin.urls')),
This way the reverse used in the internals of the django-nested-admin package will work.
I had the same problem. This is what my settings.py and urls.py look like
settings.py
INSTALLED_APPS = [
'nested_admin',
'django.contrib.admin',
# ...
]
urls.py
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^nested_admin/', include('nested_admin.urls')),
#...
]
Now, don't go to yourproject.com/nested_admin but yourproject.com/admin .
You still need the include for nested_admin or it won't work.

Django some URLs don't work

I've been making some URLs in Django, including them and so on. Everything looks fine, but no matter what i do i always end up with a 404 on some of the simplest URLs.
For example I can browse myapp/0 abd myapp/1/details/, but i get 404'd at myapp/foo
So here are my urlconf :
urlpatterns = [
url(r'^admin/', include(admin.site.urls)),
url(r'^myapp/', include('myapp.urls')),
]
and myapp urlconf :
urlpatterns = [
url(r'^foo/$ ', FooView.as_view()),
url(r'^(?P<bar_id>\d+)/$', BarByIdView.as_view()),
url(r'^(?P<bar_id>\d+)/details/$', BarDetailsByIdView.as_view()),
]
And when i tryp myapp/foo Django shows me the following urls list :
^admin/
^myapp/ ^foo/$
^myapp/ ^(?P<bar_id>\d+)/$
^myapp/ ^(?P<bar_id>\d+)/details/$
In the myapp.conf you have added a / at the end of the url pattern
url(r'^foo/$ ', FooView.as_view()
This must be viewed with /myapp/foo/ and not /myapp/foo because the first one matches the regex where as the second one won't.
Your URL is /myapp/foo/, not /myapp/foo. Note the trailing slash.
If you want both to work, ensure you have the APPEND_SLASH setting set to True and the CommonMiddleware enabled.

Categories