I am trying to route all unknown URLs to a single view. However, in doing this my known URLs only work when they do not have a trailing slash, despite setting APPEND_SLASH to True in "settings.py".
Here is some code:
settings.py:
APPEND_SLASH = True
ADMIN_URL = "admin/"
urls.py:
from django.conf import settings
from django.contrib import admin
from django.urls import include, path, re_path
from myapp.views import my_catch_all_view
urlpatterns = [
path(settings.ADMIN_URL, admin.site.urls),
re_path(r"^.*", my_catch_all_view),
]
If I go to "localhost:8000", I correctly get routed to my catch-all view.
And if I go to "localhost:8000/foobar/", I correctly get routed to my catch-all view.
And if I go to "localhost:8000/admin/", I correctly get routed to the admin view.
But, if I go to "localhost:8000/admin", I incorrectly get routed to my catch-all view.
I have seen this answer, but unfortunately that doesn't work for me.
Any suggestions?
Related
I have DRF application with urls defined using SimpleRouter.
# project/app/urls.py:
from rest_framework.routers import SimpleRouter
from .viewsets import ExampleViewset, TopViewset
router = SimpleRouter()
router.register(r"example/", ExampleViewSet, basename="example")
I imported this router to main project urls file.
# project/urls.py:
from project.app.urls import router as app_router
from django.contrib import admin
from django.urls import include, path
urlpatterns = [
path("admin/", admin.site.urls),
path("app/", include(app_router.urls)),
]
GET localhost:8000/app/example/ returns 404.
Opening localhost:8000/app/example/ in browser returns this error page:
Page not found (404)
Request Method: GET
Request URL: http://localhost:8000/app/example/
Using the URLconf defined in backend.urls, Django tried these URL patterns, in this order:
admin/
app/ ^example//$ [name='example-list']
app/ ^example//(?P<pk>[^/.]+)/$ [name='example-detail']
The current path, app/example/, didn’t match any of these.
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.
I expected app/example in URLconf, but instead there is app/ ^example. I think ^ means beginning of line. So my question is, why this happened and how to fix it?
I had to remove trailing slashes from registrations:
router.register(r"example", ExampleViewSet, basename="example")
Now correct url is generated.
first of I want to apologize if I use the wrong terms or words in my question. I'm completely new to Django and got only a few months of experience with python. I hope you can understand my question anyways. I also want to acknowledge the fact that I'm using some imports that are not needed here and might not be relevant to the latest version of Django, I'm starting to get lost in all the things I've tried from other threads to solve my problem.
I'm having some problems with showing a page from apps url.
I'm getting redirected to my homepage when trying to reach localhost:8000/articles (because /articles gives 404 error)
I'm not sure exactly what code I need to include here, so bear with me.
articles/urls.py and articles/views.py
from django.conf.urls import url
from django.urls import include, path
from django.conf.urls import include, url
from django.urls import path
from .import views
urlpatterns = [
path('^$', views.article_list),
]
from django.shortcuts import render
from django.http import HttpResponse
# views
def article_list(request):
return render(request, "articles/article_list.html")
The project's urls.py and project's views.py
from django.contrib import admin
from django.urls import path
from django.conf.urls import url, include
from django.urls import include, path
from django.conf.urls import include, url
from django.urls import path, re_path
from .import views
urlpatterns = [
path('admin/', admin.site.urls),
path('articles/', include('articles.urls')),
path('about/', views.about),
re_path('^.*$', views.homepage)
]
from django.http import HttpResponse
from django.shortcuts import render
#Views
def homepage(request):
# return HttpResponse('homepage')
return render(request, "homepage.html")
def about(request):
# return HttpResponse('about')
return render(request, "about.html")
Im getting no errors or such.
So, my question is - does anybody have a clue why /articles generate 404 error?
Thank you in advance.
Firstly, don't use ^$ with path(). You only use regular expressions with re_path.
path('', views.article_list),
Usually, /articles will be redirected to /articles/ with a trailing slash.
However, in your case, you have a catch-all pattern:
re_path('^.*$', views.homepage)
This matches /articles, so you see the home page. Note it's not redirected as you say in your answer, the browser bar will still show /articles.
Unless you have a really good reason to have the catch all, I suggest you remove it and change it to
re_path('^$', views.homepage),
or
path('', views.homepage),
That way, you'll see the homepage for localhost:8000, localhost:8000/articles will be redirected to localhost:8000/articles/, and you'll get a 404 for pages that don't exist, e.g. localhost:8000/art/
Just using a empty string '' instead of '^$:
urlpatterns = [
path('', views.article_list),
]
Take a look at the last example here: https://docs.djangoproject.com/en/3.1/topics/http/urls/#url-namespaces-and-included-urlconfs
*I don't know what django version are you using, but for regular expressions paths you should use re_path() https://docs.djangoproject.com/en/3.1/ref/urls/#django.urls.re_path
I'm developing my first app in Django and facing some issues. The server runs smoothly and I can operate the admin panel without any issues.
However, all of the app pages including the default homepage show a "404 not found" error.
I have created a templates directory in project root
updated this line in settings.py for templates,
'DIRS': [os.path.join(BASE_DIR,'templates')],
View for the app
from django.shortcuts import render
from .models import *
# Create your views here.
def customers(request):
customers = Customer.objects.all()
return render(request, "customers.html", {'customers': customers})
urls for the app
from django.urls import path from . import views
urlpatterns = [path('customers',views.customers, name='customers')]
urls for the project
from django.contrib import admin from django.urls import path, include from django.conf import settings from django.conf.urls.static import static
urlpatterns = [
path('trips/',include('trips.urls')),
path('customers/',include('customers.urls')),
path('drivers/',include('drivers.urls')),
path('vehicles/',include('vehicles.urls')),
path('admin/', admin.site.urls), ]
urlpatterns = urlpatterns + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
Help is appreciated
I can't see any problem with your case, you should be able to load http://localhost:8000/customers/customers. Maybe double customers was not you intention, then remove one of them (one in main urls.py one in app's).
Also when Django debug mode is active and you get a 404 because of URL mismatch, it shows you a list of URLs you have. To see it navigate to a non existing URL like http://localhost:8000/aaa. Then if you see customers/ there try http://localhost:8000/customers/. Go step by step to find the problem.
I am trying to use Django's account system, including the #login_required decorator. My settings.py file includes django.contrib.auth and I have done a syncdb.
Page not found (404)
Request Method: GET
Request URL: http://localhost:8000/accounts/login/?next=/
Using the URLconf defined in dashboard.urls, Django tried these URL patterns, in this order:
^$ [name='home']
The current URL, accounts/login/, didn't match any of these.
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.
I see the above after trying to #login_required-decorate my home view.
It seems to be choking because it is redirected to accounts/login/, which I have not prepared for in my urls.py.
What can I add to urls.py or elsewhere so that the login_required decorator will do its usual behaviour?
Thanks,
Set the LOGIN_URL in your settings. The default value is '/accounts/login/'
The decorator also takes an optional login_url argument:
#login_required(login_url='/accounts/login/')
And, from the docs:
Note that if you don’t specify the login_url parameter, you’ll need to
ensure that the settings.LOGIN_URL and your login view are properly
associated. For example, using the defaults, add the following line to
your URLconf:
(r'^accounts/login/$', 'django.contrib.auth.views.login'),
path('accounts/login/', admin.site.urls),
Add this line in your urls.py project folder. Then it will work fine.
from django.contrib.auth.decorators import login_required
#login_required(login_url='/accounts/login/')
Add above two lines in your views.py file.
What worked for me in Django 2.2.1 - include re_path('^accounts/', admin.site.urls), in my project urls.py:
urls.py
from django.conf import settings
from django.conf.urls import include
from django.conf.urls import re_path
from django.conf.urls.static import static
from django.contrib import admin
from django.urls import path
urlpatterns = [
path('admin/', admin.site.urls),
re_path('^accounts/', admin.site.urls),
]
And in my views.py:
views.py
from django.contrib.auth.decorators import login_required
from django.views.generic import TemplateView
#method_decorator(login_required, name='dispatch')
class HomePageView(TemplateView):
"""
Home Page View
"""
template_name = 'amp/home.html'
Hope that helps.
UPDATE: To avoid warnings from django in regards to admin urls being loaded twice, I used a redirect instead in urls.py:
urls.py
urlpatterns = [
re_path('^accounts/', admin.site.urls),
re_path(r'^admin/', RedirectView.as_view(url='/accounts/', permanent=True))
]
More on redirect view here.
I'm using the new i18n_patterns of Django 1.4:
from django.conf.urls import patterns, include, url
from django.conf.urls.i18n import i18n_patterns
from django.contrib import admin
admin.autodiscover()
urlpatterns += i18n_patterns('',
url(r'^admin/', include(admin.site.urls)),
)
It works for every active language:
/en/admin/ # Ok
/es/admin/ # Ok
But this fails:
/admin/ # 404 Not found
How to avoid the 404 error and redirect to a language-prefixed version of the requested URL (not only the admin panel)?
Is to write a custom middleware the solution? Why this doesn't come by default in Django?
It looks like you did not enable django.middleware.locale.LocaleMiddleware.