Adding a trailing slash to a Django root URL - django

I am serving through Apache and wsgi a Django Project. The server url is http://example.com and the alias for the project is myProject
I'm trying to add automatically a trailing slash to the root url, therefore:
http://example.com/myProject
should become
http://example.com/myProject/
In the Apache settings, I have the project alias:
WSGIScriptAlias /myProject /path/to/wsgi.py
In the myProject's main urls.py file for Django, I have these entries:
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'', include('externalModule.urls')), # I need to add the urls of an external module at this point.
]
But doing in this way, if I request http://example.com/myProject the trailing slash is not added and it causes errors later on, during the site usage, due to some relative links.
Intrestingly, if I change urls.py:
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'foo/', include('externalModule.urls')),
]
It works: http://example.com/myProject/foo becomes http://example.com/myProject/foo/.
How can I get the same behavior at the root level?

Related

404 error when requesting a file that exists

I'm trying to deploy a Django project using a VPS - it uses Apache and mod_wsgi. (It works fine locally).
My homepage is displayed, but no static file is found, leading to a goofy display.
I have configured my static files this way :
settings.py :
STATIC_ROOT = os.path.join(BASE_DIR, 'static')
STATIC_URL = '/static/'
urls.py
urlpatterns = [
path('', home, name='home'),
path('output/<str:region>/<str:summoner_name>', output, name='output')
] + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
call in template :
After that I ran collectstatic, which created a "static" folder on root, as expected. I have checked via SSH and FTP, it is there : see here, with the correct permissions.
The URL to access it should then be : mywebsiteurl/static.
But I get this 404 error, even though my explorer seems to look for the correct adress :
I simply don't understand how can I get a 404 when requesting a file that seems to exist.

Wagtail {{document.url}} is returning a 404 for user-uploaded files, in production

I've inherited a Wagtail CMS project but have been unable to solve an issue relating to document uploads.
Having uploaded a file through the CMS, it arrives in the documents directory /var/www/example.com/wagtail/media/documents/test_pdf.pdf which maps to the /usr/src/app/media/documents/test_pdf.pdf directory inside the docker container.
In the front end (and within the Wagtail dashboard) the document.url resolves to https://example.com/documents/9/test_pdf.pdf/ which returns a 404. Obviously the model number segment is missing from the file path above, but I read on a forum that
In Wagtail, documents are always served through a Django view (wagtail.wagtaildocs.views.serve.serve) so that we can perform additional processing on document downloads
so perhaps this, in itself, is not an issue.
There are a couple of lines in urls.py file which look correct:
urlpatterns = [
url(r'^django-admin/', admin.site.urls),
url(r'^admin/', include(wagtailadmin_urls)),
url(r'^documents/', include(wagtaildocs_urls)),
url(r'^search/$', search_views.search, name='search'),
url(r'^sitemap\.xml$', sitemap),
url(r'', include(wagtail_urls)),
# url(r'^pages/', include(wagtail_urls)),
]
if settings.DEBUG:
...
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
and in base.py
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
MEDIA_URL = '/media/
So, my hunch is one of either:
Uploads being stored incorrectly, in a single folder rather than in subdirectories by model
The routing to this “virtual” directory is broken, so it’s breaking at the "check permissions" stage (but I couldn't figure out how routing works in Django) and returning the 404
The web server is incorrectly configured, so whilst the “virtual” URL is fine it’s actually the file URL which is broken and THIS causes the 404 (my nginx contains a /media/ location but not a /documents/ location, as I would have expected)
Something else entirely (my next step is to pull a copy down to my own machine and see if the issue still occurs)
I appreciate there isn't much to go on here but I'm hoping that someone might be able to give me some pointers as to what else I should check, as I've been banging my head against this for most of the day.
My background is with Ruby on Rails so, as with that framework, I've a feeling that there is a lot of "magic" happening behind-the-scenes that is making it very tricky to figure out what's going on.
Thanks!
You are able to see documents while developing because of
if settings.DEBUG:
...
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
Like static files media files should be handled on server level. For example, if you are using GCP you need to update your app.yaml and add media/ the same way as static/
...
handlers:
- url: /static
static_dir: static/
- url: /media
static_dir: media/
...

URLpattern match doesn't work as expected

What I want
I'm running the very first steps of the Django Project tutorial and there's already something i can't get right.
The idea behind include() is to make it easy to plug-and-play URLs. Since polls are in their own URLconf (polls/urls.py), they can be placed under “/polls/”, or under “/fun_polls/”, or under “/content/polls/”, or any other path root, and the app will still work.
I built everything as needed and my 'shelves' server works fine (debug here, running on localhost).
I'm setting the urlpatterns in shelves.urls, the first of which tries to include 'bluebook.urls'.
from django.contrib import admin
from django.urls import include, path
urlpatterns = [
path('bluebook/', include('bluebook.urls')),
path('admin/', admin.site.urls),
]
When I go to http://127.0.0.1:8000/bluebook/, it works fine and loads the views.index I set up.
What doesn't work
When I go to http://127.0.0.1:8000/thebluebook/, it throws a 404. It goes as far as defining regex match not working :
Using the URLconf defined in shelves.urls, Django tried these URL patterns, in this order:
1. bluebook/
2. admin/
The current path, thebluebook/, didn't match any of these.
It does the same with http://127.0.0.1:8000/the_bluebook/ or http://127.0.0.1:8000/go/bluebook/.
What I tried
I haven't written much code so there's not much to join to this summary. Although the error message only mentions shelves.urls, i checked that bluebook.urls is set to accept any regex after the redirection from shelves.urls :
from django.urls import path
from . import views
urlpatterns = [
path('', views.index, name='index'),
]
I checked Django Tutorial Part 1 Error: URL does not match URL patterns and tried to change ROOT_URLCONF from 'shelves.urls' to 'urls', but it throws a ERR_CONNECTION_REFUSED instead of a 404, whatever I put after http://127.0.0.1:8000/, basically the site doesn't work anymore.
I checked out Page not found 404 on Django site? but my site's urls.py is in the child folder mysite/, not the parent mysite/.
I also tried
urlpatterns = [
path('bluebook/', 'bluebook.urls'),
path('admin/', admin.site.urls),
]
but it doesn't work either.
Basically, all my setup looks right to me as calling the exact URLpattern works as expected. Only the regex matching doesn't seem to work.
FWIW, I'm using JetBrain's PyCharm to edit the code and setup the venv, without the plugin, but I don't see it influencing the running of Django code.
Python-version : Python 3.6.5 (v3.6.5:f59c0932b4, Mar 28 2018, 17:00:18) [MSC v.1900 64 bit (AMD64)] on win32
Django version : 2.0.7
PyCharm version : 2018.1.4
Chrome version : Version 67.0.3396.99 (Official Build) (64-bit)
You didn't include 'thebluebook' in your urls. you have path('bluebook/', include('bluebook.urls')), and path('', views.index, name='index'),
which means you can do http://127.0.0.1:8000/bluebook/any/thing/here/ but you can not http://127.0.0.1:8000/any/thing/here/bluebook/.

Django url mapping for similar patterns

My dir structure is as follows:
mainFolder
--myProject
---urls.py
--mysite
---urls.py
In myProject folder's urls.py I have:
url(r'^$', 'mysite.views.home', name='home'),
I changed it to
url(r'^$', include(mysite.urls)),
I would like my application to use mysite.urls.py for all requests, e.g.
localhost:8000/ OR
localhost:8000/abc OR
localhost:8000/def
etcetera
How do I configure the url parameters in myProject.urls.py in order to do this?
url(r'', include(mysite.urls)),
You have to remove the '$' from the url pattern.
You can use the following syntax
url(r'^', include(mysite.urls))
More info on why "^$" is used can be found here

{% url admin:index %} generating wrong urls

My django site is served up with the following in Apache's config:
WSGIScriptAlias /studio /django/studio/bin/django.wsgi
My urls.py looks like:
urlpatterns += patterns(
'django.contrib',
(r'^admin/', include(admin.site.urls)),
(r'^accounts/login/$', 'auth.views.login'),
(r'^accounts/logout/$', 'auth.views.logout'),
)
...and yet:
[admin]
...generates a link to /admin rather than /studio/admin.
Bizarrely, the urls within the admin interface itself are fine.
I'm using:
Python 2.5.2-3
Django 1.1.1
mod_wsgi 2.5-1~lenny1
apache2 2.2.9-10+lenny6
Can anyone tell me what I'm doing wrong?
cheers,
Chris
This is a bug in Django, see:
http://code.djangoproject.com/ticket/12464
The problem is that because Apache's rewrite engine is on as a result of rewriting I need to do elsewhere in the virtual host, the SCRIPT_URL environment variable is set. But, when a request is made to /project through Apache, PATH_INFO is empty, which results in SCRIPT_NAME being incorrectly set as an empty string.
Until this bug is fixed, inserting the following RewriteRule into the Apache configuration will safely work around the problem by ensuring that PATH_INFO is never empty.
RewriteEngine On
RewriteRule ^/project$ /project/ [R]
WSGIScriptAlias /project /django/project/bin/django.wsgi
Your Django instance knows nothing about the /studio part of the URL as it is handled in WSGI. You have to manually prepend it either in templates or, better, in urls.py:
in settings.py:
BASE_URL = '/studio'
in urls.py:
r('^%s/admin/' % settings.BASE_URL, include(admin.site.urls)), ...
Then your url reversing will work as expected. You admin links work because once you are in the admin interface all links are relative.