I have a web page served by Django, and i want to make it to 301 redirect from
mysite.com/ to mysite.com without a slash on the end. Is it possible to do with Django?
Last version of Django, python 3.6.
path("", views.home, name="main_page")
Changing nginx config is not an option at my server
mysite.com/ and mysite.com are the same URL. You don't need to set up a redirect.
Your friend probably means that you shouldn't have the same content for mysite.com/foo and mysite.com/foo/.
In Django, you would usually achieve this by using the URL foo/, then the default setting APPEND_SLASH = True will redirect /foo to /foo/.
Related
I've deployed my Django (DRF API) project on DigitalOcean apps. The path "/" is used by my static site that uses this API so I set route for this component to "/api" which works correctly.
The problem:
I go to /api/admin/ and it redirects me to /admin/login but the django is served on /api url so this URL is invalid.
Do you know how to make this work?
Is there a way to tell django to use absolute URL everywhere?
urls.py
urlpatterns = [
...
path("api/admin/", admin.site.urls),
...
]
In urls.py I have:
path('/admin/', admin.site.urls),
path('/admin/login', login_required(admin.site.login)),
path('/customlogin/', include('customlogin.urls', namespace='customlogin'))
This redirects to a custom authentication view, specified in settings.LOGIN_URL.
When you go to /admin it redirects to /admin/login/?next=/admin, which does not redirect to LOGIN_URL. But when you go to /admin/login directly, everything works correctly.
Note: This worked correctly in Django 1.11.
To match the admin login url, your path should have a trailing slash. You also have to move your path above admin.site.urls, so that Django uses your decorated view.
path('/admin/login/', login_required(admin.site.login))
path('/admin/', admin.site.urls),
I am working on a project that uses Django and Angular. I do not have a background as a web developer so please try to explain your answer so that a novice person can understand it.
Basically I want to make it so that the login page is the default page instead of the index page.
I currently have the following url handler in my main Django project urls.py:
url(r'^$', 'core.views.generic.index')
I also have another urls.py in an app called core that sends visitors to the login page:
url(r'^/login$', private.MeLogin.as_view())
Now I want the login page to become the default page instead if the index page. How can I do that?
I have tried adding the following the the views file in the core app:
#login_required(redirect_field_name='', login_url='#/login')
def index(request):
return render_to_response('html/index.html', locals(), context_instance=RequestContext(request))
Unfortunately I get the message
This webpage has a redirect loop
I do not know how to solve this problem. Basically I want users to be redirected to the login page if they enter any URL that is not handled by other URL handlers. When they successfully log in they are redirected to a dashboard page automatically.
EDIT:
The login page URL is handled in the core urls.py file and points to a different view than index.
url(r'^/login$', private.MeLogin.as_view())
Web servers, in this case Django, do not see the fragment after the #. You are redirecting from / to /, creating a redirect loop.
If you want to redirect to the Django login url, you need login_url='/login'.
As an aside, you should remove the leading slash from your regex r'^/login$.
In #login_required(redirect_field_name='', login_url='#/login')
remove redirect_field_name='', it really is not neccessary and make sure that #/login in login_url='#/login is the same as in your url.py file:
like
views.py
#login_required(redirect_field_name='', login_url='accounts/login/')
as
url.py
url(r'^accounts/login/', auth_views.login),
I assume your Angular & Django apps are running in two seperate ports, like:
Django on port 8000
Angular on port 1000
So if you give /#/login it will redirect for the same with Django port (8000/#/login).
So why don't you give the full URL www.example.com/#/login?
I have a single Django app that handles two (or more) parts of site, for example an "admin" and an "api" sections of the site. I also have normal html pages for the rest of the site, where no Django is needed.
I want to have the static html site on the root of my site, and the Django app on some sub-locations, for example
www.example.com -> Apache static html site
www.example.com/admin/ -> Django app, serving the pages for the admin
www.example.com/api/ -> Django app, serving the pages for the api
At first I try to do so all form Django, using the urls like so:
# my_app/urls.py
...
url(r'^admin/', include('admin.urls')),
url(r'^api/', include('api.urls')),
url(r'^(?P<path>.*)$', ??????????),
...
But I couldn't figure out a good way to delegate the serving of those static pages to Apache. (It did work if I use url(r'^(?P<path>.*)$, 'django.views.static.serve', {'document_root': '/path/to/static/site'}), but the Django documentation forbids to use that on a production server.)
Then I tried with the apache configuration:
# httpd.conf
...
DocumentRoot /path/to/static/site
WSGIScriptAlias /admin /path/to/django/my_app/wsgi.py
WSGIScriptAlias /api /path/to/django/my_app/wsgi.py
...
This worked as far as requests to root returned the static site and requests to both "admin" and "api" would return the Django site, but within Django I found no way to distinguish if the request came from '/admin' or from '/api'. (Plus I'm not sure if having two WSGIScriptAlias pointing at the same wsgi might cause some problems.)
If someone knows of a way to achieve this without having to split my Django app into two (or more) parts it would be greatly appreciated.
I had the almost exact same problem. In Apaches virtual host config for the site use
WSGIScriptAliasMatch ^(/(admin|api)) /path/to/django/my_app/wsgi.py$1
instead of
WSGIScriptAlias /admin /path/to/django/my_app/wsgi.py
WSGIScriptAlias /api /path/to/django/my_app/wsgi.py
Check these Q&A for further information:
Django (wsgi) and Wordpress coexisting in Apache virtualhost
Reconfiguring Apache to serve website root from new php source and specific sub-urls from old django site
When I was using the built-in simple server, everything is OK, the admin interface is beautiful:
python manage.py runserver
However, when I try to serve my application using a wsgi server with django.core.handlers.wsgi.WSGIHandler, Django seems to forget where the admin media files is, and the admin page is not styled at all:
gunicorn_django
How did this happen?
When I look into the source code of Django, I find out the reason.
Somewhere in the django.core.management.commands.runserver module, a WSGIHandler object is
wrapped inside an AdminMediaHandler.
According to the document, AdminMediaHandler is a
WSGI middleware that intercepts calls
to the admin media directory, as
defined by the ADMIN_MEDIA_PREFIX setting, and serves those images.
Use this ONLY LOCALLY, for development! This hasn't been tested
for
security and is not super efficient.
And that's why the admin media files can only be found automatically when I was using the test server.
Now I just go ahead and set up the admin media url mapping manually :)
Django by default doesn't serve the media files since it usually is better to serve these static files on another server (for performance etc.). So, when deploying your application you have to make sure you setup another server (or virtual server) which serves the media (including the admin media). You can find the admin media in django/contrib/admin/media. You should setup your MEDIA_URL and ADMIN_MEDIA_URL so that they point to the media files. See also http://docs.djangoproject.com/en/dev/howto/static-files/#howto-static-files.
I've run into this problem too (because I do some development against gunicorn), and here's how to remove the admin-media magic and serve admin media like any other media through urls.py:
import os
import django
...
admin_media_url = settings.ADMIN_MEDIA_PREFIX.lstrip('/') + '(?P<path>.*)$'
admin_media_path = os.path.join(django.__path__[0], 'contrib', 'admin', 'media')
urlpatterns = patterns('',
url(r'^admin/', include(admin.site.urls)),
url(r'^' + admin_media_url , 'django.views.static.serve', {
'document_root': admin_media_path,
}, name='admin-media'),
...
)
Also: http://djangosnippets.org/snippets/2547/
And, of course, #include <production_disclaimer.h>.