Django routing - The empty path didn't match any of these - django

Very basic question and I was surprised I wasn't able to find an answer. I'm just starting looking at django and did an out-of-box intallation. Created a project and created an app.
The default content of urls.py is very simple:
urlpatterns = [
path('admin/', admin.site.urls),
]
And if I open the django site home page, I get the content with a rocket picture. However, like I said, I have created another app in the project, let's say called 'bboard'. And I have created a simple 'hello world' function in bboard/views.py
def index(request):
return HttpResponse('Hello world')
to enable it for access through browser, I have modified the original urls.py file in the following way:
from bboard.views import index
urlpatterns = [
path('admin/', admin.site.urls),
path('bboard/', index),
]
This way I can access localhost:port/admin and localhost:port/bboard URLs, but if I try to open the home page with localhost:port now, I get Page not found error.
Using the URLconf defined in samplesite.urls, Django tried these URL patterns, in this order:
admin/
bboard/
The empty path didn't match any of these.
if I comment out the second item in urlpatterns list, everything works. So why does the additional pattern impact this and what needs to be done to fix it?

You need to add an empty url in root urls.py
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('bboard.urls'))
]

Before you add your own routes Django will serve the default home page at the '/' url. After you add your own route config, django no longer serves up its default sample home page.
From the django's django/views/debug.py:
def technical_404_response(request, exception):
"""Create a technical 404 error response. `exception` is the Http404."""
try:
error_url = exception.args[0]['path']
except (IndexError, TypeError, KeyError):
error_url = request.path_info[1:] # Trim leading slash
try:
tried = exception.args[0]['tried']
except (IndexError, TypeError, KeyError):
tried = []
else:
if (not tried or ( # empty URLconf
request.path == '/' and
len(tried) == 1 and # default URLconf
len(tried[0]) == 1 and
getattr(tried[0][0], 'app_name', '') == getattr(tried[0][0], 'namespace', '') == 'admin'
)):
return default_urlconf(request)
Note the final else block that returns a default_urlconf if the only url path included is the admin path and the requested url is /. This default_urlconf is the sample Rocket page you mentioned. As soon as you add any of your own routes the if statement in the else block will be false so the default_urlconf is not returned and instead falls through to the normal 404 handler.
Here's the default_urlconf
def default_urlconf(request):
"""Create an empty URLconf 404 error response."""
with Path(CURRENT_DIR, 'templates', 'default_urlconf.html').open() as fh:
t = DEBUG_ENGINE.from_string(fh.read())
c = Context({
'version': get_docs_version(),
})
return HttpResponse(t.render(c), content_type='text/html')

The other reason that you might be getting this error is because
You haven't passed an empty URL inside your application URL
Kindly (this is a simple but a very crucial one) check for typos

Related

Extra space showing in end url

I am having an issue with Panda. I am trying to add a new views to my website and when I type this line in the product/urls.py file I get an error stating that the endpoint was not found by Panda - Page not found (http://127.0.0.1:8000/products/new/)
Using the URLconf defined in pyshop.urls, Django tried these URL patterns, in this order:
admin/
products/
products/ new
The current path, products/new/, didn't match any of these.
I have created a new function to hold the new products view
def new(request):
return HttpResponse('New Product')
Then I have mapped the endpoint in the products/urls.py file
urlpatterns = [
path('', views.index),
**path('new', views.new)**
]
P.S. The index is behaving as expected
The space is just formatting to show that these is a set of suburls. The problem is the trailing slash:
urlpatterns = [
path('', views.index),
path('new/', views.new)
]

Page not found (404), The empty path didn’t match any of these [duplicate]

Very basic question and I was surprised I wasn't able to find an answer. I'm just starting looking at django and did an out-of-box intallation. Created a project and created an app.
The default content of urls.py is very simple:
urlpatterns = [
path('admin/', admin.site.urls),
]
And if I open the django site home page, I get the content with a rocket picture. However, like I said, I have created another app in the project, let's say called 'bboard'. And I have created a simple 'hello world' function in bboard/views.py
def index(request):
return HttpResponse('Hello world')
to enable it for access through browser, I have modified the original urls.py file in the following way:
from bboard.views import index
urlpatterns = [
path('admin/', admin.site.urls),
path('bboard/', index),
]
This way I can access localhost:port/admin and localhost:port/bboard URLs, but if I try to open the home page with localhost:port now, I get Page not found error.
Using the URLconf defined in samplesite.urls, Django tried these URL patterns, in this order:
admin/
bboard/
The empty path didn't match any of these.
if I comment out the second item in urlpatterns list, everything works. So why does the additional pattern impact this and what needs to be done to fix it?
You need to add an empty url in root urls.py
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('bboard.urls'))
]
Before you add your own routes Django will serve the default home page at the '/' url. After you add your own route config, django no longer serves up its default sample home page.
From the django's django/views/debug.py:
def technical_404_response(request, exception):
"""Create a technical 404 error response. `exception` is the Http404."""
try:
error_url = exception.args[0]['path']
except (IndexError, TypeError, KeyError):
error_url = request.path_info[1:] # Trim leading slash
try:
tried = exception.args[0]['tried']
except (IndexError, TypeError, KeyError):
tried = []
else:
if (not tried or ( # empty URLconf
request.path == '/' and
len(tried) == 1 and # default URLconf
len(tried[0]) == 1 and
getattr(tried[0][0], 'app_name', '') == getattr(tried[0][0], 'namespace', '') == 'admin'
)):
return default_urlconf(request)
Note the final else block that returns a default_urlconf if the only url path included is the admin path and the requested url is /. This default_urlconf is the sample Rocket page you mentioned. As soon as you add any of your own routes the if statement in the else block will be false so the default_urlconf is not returned and instead falls through to the normal 404 handler.
Here's the default_urlconf
def default_urlconf(request):
"""Create an empty URLconf 404 error response."""
with Path(CURRENT_DIR, 'templates', 'default_urlconf.html').open() as fh:
t = DEBUG_ENGINE.from_string(fh.read())
c = Context({
'version': get_docs_version(),
})
return HttpResponse(t.render(c), content_type='text/html')
The other reason that you might be getting this error is because
You haven't passed an empty URL inside your application URL
Kindly (this is a simple but a very crucial one) check for typos

Django 404 Error page not found...the current path matched the last one

I'm new to django and I'm playing around with my own variation of the polls tutorial. My app was working fine, every page loaded correctly. Then I made a single change; I created and then deleted a model. Now, many of urls seem broken. And I don't understand this error:
Page not found (404)
Request Method: GET
Request URL: http://127.0.0.1:8000/polls/1/pick/
Raised by: polls.views.pick
Using the URLconf defined in mySite.urls, Django tried these URL patterns, in this order:
polls/ [name='index']
polls/ <int:pk>/ [name='detail']
polls/ <int:pk>/results/ [name='results']
polls/ <int:question_id>/vote/ [name='vote']
polls/ <int:question_id>/tally/ [name='tally']
polls/ <int:question_id>/pick/ [name='pick']
The current path, polls/1/pick/, matched the last one.
You’re seeing this error because you have DEBUG = True in your Django settings file. Change that to False, and Django will display a standard 404 page.
So I don't understand why it says both that: The current path, polls/1/pick/, matched the last one.
and also page not found? How does that work? And what could have caused this when the app was working fine previously?
My urls.py:
from django.urls import path
from . import views
app_name = 'polls'
urlpatterns = [
path('', views.IndexView.as_view(), name='index'),
path('<int:pk>/', views.DetailView.as_view(), name='detail'),
path('<int:pk>/results/', views.ResultsView.as_view(), name='results'),
path('<int:question_id>/vote/', views.vote, name='vote'),
path('<int:question_id>/tally/', views.tally, name='tally'),
path('<int:question_id>/pick/', views.pick, name='pick'),
path('<int:pk>/video/', views.VideoView.as_view(), name='video'),
path('<int:pk>/reveal/', views.RevealView.as_view(), name='reveal'),
]
And views snippit:
def pick(request, question_id):
question = get_object_or_404(Question, pk=question_id)
player = get_object_or_404(Player, pk=1)
question.score = player.score
question.save()
return HttpResponseRedirect(reverse('polls:video', args=(question.id,)))
This line of the error
Raised by: polls.views.pick
Is telling you that you didn't get a 404 due to not finding a matching URL, you got a 404 because your view function polls.views.pick raised a 404. You have two lines in that function that could raise a 404
question = get_object_or_404(Question, pk=question_id)
player = get_object_or_404(Player, pk=1)
So in your database, you either don't have a Question with pk=1 or you don't have a Player with pk=1.

How do you pass 'exception' argument to 403 view?

**Edit: Of course, it dawns on me that this doesn't have anything to do with the UserPassesTextMixin, because this error pops up when trying to visit the 403 page directly. Still not sure what to make of it though.
I'm attempting to use UserPassesTestMixin to check which model's edit view is being requested and run a test specific to that model to see if the user should have access. Nothing is working yet, I'm just trying to get a feel for how this mixin operates. Upon returning false in the test_func, the view tries to redirect to /403/, but I get the below error.
TypeError at /403/
permission_denied() missing 1 required positional argument: 'exception'
view
class DeviceUpdate(LoginRequiredMixin, UserPassesTestMixin, UpdateView):
model = Device
template_name_suffix = '_update_form'
form_class = DeviceUpdateForm
def test_func(self):
return edit_permission_test(self.get_object())
...
perms.py
def edit_permission_test(model_object):
possible_models = ['Device',]
if isinstance(model_object, Device):
print('This is a Device model object')
return True
else:
print('This doesnt look like a Device model object')
return False
I cant seem to find anything out there on the interwebs that helps with this error.
I think this issue just had to do with how the url patterns were configured for local development. Previously my main urls.py looked like this:
urlpatterns = [
url(r'^$', TemplateView.as_view(template_name='pages/home.html'), name="home"),
...
# Your stuff: custom urls includes go here
url(r'^devices/', include('auto_toner.urls', namespace='auto_toner', app_name='auto_toner'), name="devices"),
url(r'^400/$', default_views.bad_request),
url(r'^403/$', default_views.permission_denied),
url(r'^404/$', default_views.page_not_found),
url(r'^500/$', default_views.server_error),
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
I changed the URLs to include kwargs in the pattern if settings.DEBUG was True.
if settings.DEBUG:
# This allows the error pages to be debugged during development, just visit
# these url in browser to see how these error pages look like.
urlpatterns += [
url(r'^400/$', default_views.bad_request, kwargs={'exception': Exception('Bad Request!')}),
url(r'^403/$', default_views.permission_denied, kwargs={'exception': Exception('Permission Denied')}),
url(r'^404/$', default_views.page_not_found, kwargs={'exception': Exception('Page not Found')}),
url(r'^500/$', default_views.server_error),
]
if 'debug_toolbar' in settings.INSTALLED_APPS:
import debug_toolbar
urlpatterns += [
url(r'^__debug__/', include(debug_toolbar.urls)),
]

Django Unable to Find reverse() URL

I have the following URLConf setup:
urlpatterns = patterns('myapp.views',
url(r'^$', 'index', name="home"),
url(r'^login$', 'login'),
)
So far in my views, I have this:
def index(request):
"""Displays paginated message views"""
return HttpResponseRedirect(reverse("myapp.views.login"))
def login(request):
"""Displays login screen"""
return render_to_response('myapp/login.html', {
"title": "Login"
})
The problem arises when I try to go to the login page. Django seems to be unable to find my URL.
Going to the url http://localhost:8000/login, I receive the following error:
Page not found (404)
Request Method: GET Request
URL: http://localhost:8000/login
'login' could not be found
You're seeing this error because you have DEBUG = True in your Django
settings file. Change that to False, and Django will display a
standard 404 page.
It seems that even though I am using the reverse function to find Django's own recommended URL based on my URLConf, it is still unable to find its own URL!
Any ideas?
EDIT:
I need to clarify somethings: The problem is not that Django is unable to figure out the correct URL, it is that once that URL is loaded, Django is unable to find the view associated with that.
can you please put name attribute to your url like this
url(r'^$', 'index', name="home"),
then call reverse with this name
examples
urlpatterns = patterns('',
url(r'^archive/(\d{4})/$', archive, name="full-archive"),
url(r'^archive-summary/(\d{4})/$', archive, {'summary': True}, "arch-summary"),
)
from django.core.urlresolvers import reverse
def myview(request):
return HttpResponseRedirect(reverse('arch-summary', args=[1945]))
It turns out the error was caused by me changing the STATIC_URL variable in my settings.py file. Changing that back to "/static/" made everything work.