Django Admin - FORCE_SCRIPT_NAME is appended twice to URL when POSTing - django

I have deployed Django to a sub directory (I don't have full control over the server so can't change the way it's deployed).
I added to my settings:
FORCE_SCRIPT_NAME = '/hub06'
STATIC_URL = FORCE_SCRIPT_NAME + '/static/'
Now when I go to /admin/hub06, it's working properly, I can login and browse all admin pages. As soon as I do a POST request though (adding a new model), the URL gets corrupted.
For example, when editing /hub06/admin/myapp/car/1
When I submit the form, it redirects to /hub06/hub06/admin/myapp/car/
So it adds script name twice. This is only for POST requests in Django admin.

Is this a linux host? is it running apache, nginx? It all depends on how your web server is configured.
If you really must have a url prefix like /hub06/ then you will need to update any settings in settings.py that return a url such as LOGIN_URL, STATIC_URL, LOGIN_REDIRECT_URL etc to contain the prefix.
I don't think you need to use FORCE_SCRIPT_NAME. Comment that bit out in the settings.py and update urls.py to add the following for example:
from django.conf.urls import patterns, include, url
from django.contrib.auth.views import login
from django.contrib import admin
admin.autodiscover()
urlpatterns2 = patterns('',
url(r'^$', 'yourapp.views.home', name='Home'),
url(r'^admin/', include(admin.site.urls)),
)
urlpatterns = patterns('',
url(r'^hub06/', include(urlpatterns2)),
)
Let me know how you go.

This was the solution:
# NB - this setting is required to make the app work correctly when running
# via ProxyPass from Apache. Otherwise CSRF checks and some redirects will not
# work.
USE_X_FORWARDED_HOST = True

Related

Uploading files POST urls raise 404 when deploy

I'm deploying a django app on a host with apache and cPanel. I think I did all the steps that django needs to deploy. Everything works fine except dome admin posts urls.
When I'm sending a form via post from the admin site, and one of its fields is a File that will be uploaded to a directory, the server responses me 404. Some info:
Python 3.5, Django 1.11.9
Error: 404 Not Found
When: sending any post form containing a Choose File field, even if the file isn't mandatory.
The forms without files in their fields work fine. In production everything works perfect.
I have a symlink in the public_html folder to my media and static folders.
This error only shows in the admin page. I can upload file from the site without any problem
This is my code:
urls.py
urlpatterns = i18n_patterns(
url(r'^admin/', admin.site.urls),
url(r'^i18n/', include('django.conf.urls.i18n')),
url(r'^', include('myapp.urls')),
prefix_default_language=False)
settings.py
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
MEDIA_URL = '/media/'
This is my first time hosting a website, so, sorry if I'm asking a dummy question, but I couldn't find any solution, even here. Also, sorry for my English. Thanks for the future answers
EDIT
My non-admin forms work perfect. The problem is in the admin page. I edited my old question with the changes in bold
It can be web server problem. Check your cPanel settings
May be something wrong with your wsgi file location
Check up some tutorial for more info.
In case you are serving media files using django's static file server, the urlpatterns variable in your project's base urls.py file should be assigned in a specific order so that the i18n_patterns(...) assignment places before the static(...) url.
you should do it like so:
urlpatterns = i18n_patterns(
url(r'^admin/', admin.site.urls),
url(r'^i18n/', include('django.conf.urls.i18n')),
url(r'^', include('myapp.urls')),
prefix_default_language=False)
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

Rewrite URL to exclude Django application name

on my live server, I am trying to remove/rewrite the need to include the application name in the URL, as without it I get a 404. For example:
http://www.example.com/myapp/page.html
to
http://www.example.com/page.html
This is especially tricky since i don't want this to affect the django admin URL which excludes the app name.
This is on Apache Server on Ubuntu on a shared host (A2).
You're root urls.py most likely looks something like this:
"""
Definition of urls for api.
"""
from django.conf import settings
from django.conf.urls import include, url
from django.conf.urls.static import static
from django.contrib import admin
urlpatterns = [
# Uncomment the admin/doc line below to enable admin documentation:
# url(r'^admin/doc/', include('django.contrib.admindocs.urls')),
url(r'^admin/', admin.site.urls),
url(r'^myapp/', include('myapp.urls'))
]
When you just replace r'^myapp/' with r'^' the app will be automatically tried, when there is nothing else before that fits (so it's best to put it to the end of the list)

How can I fix my Wagtail URL namespace and explorer when adding wagtail to a current project?

My issue is my URL is coming up mysite.com/test-news-1/ instead of mysite.com/news/test-news-1/
I've started a new project using cookiecutter-django. I then wanted to add wagtail cms to the project and followed the docs to do so.
I get the wagtail admin page up fine, at /cms/ instead of /admin/ like it says to do on this page - http://docs.wagtail.io/en/v1.3.1/getting_started/integrating_into_django.html
I added a few apps just to practice and get used to wagtail, one directly copied from the wagtail blog example. This is where my issue starts.
The wagtail admin Explorer does not list my apps like it shows on the wagtail site https://wagtail.io/features/explorer/, instead it just says "Welcome to your new Wagtail site!" When I select Add Child Page it allows me to select the app pages I have set up and seems to go by my models just fine. But when I post something and click go to live site it comes up as mysite.com/blog1/ instead of mysite.com/blog/blog1/
I believe my problem that I dont understand the final part of the doc page that I linked above. It says,
Note that there’s one small difference when not using the Wagtail
project template: Wagtail creates an initial homepage of the basic
type Page, which does not include any content fields beyond the title.
You’ll probably want to replace this with your own HomePage class -
when you do so, ensure that you set up a site record (under Settings /
Sites in the Wagtail admin) to point to the new homepage.
I tried adding the homepage model from the doc page, but this didn't seem to help at all.
I'm very inexperienced, this is my urls.py file, if you need to see other files please let me know.
urls.py
from __future__ import unicode_literals
from django.conf import settings
from django.conf.urls import include, url
from django.conf.urls.static import static
from django.contrib import admin
from django.views.generic import TemplateView
from django.views import defaults as default_views
from wagtail.wagtailadmin import urls as wagtailadmin_urls
from wagtail.wagtaildocs import urls as wagtaildocs_urls
from wagtail.wagtailcore import urls as wagtail_urls
urlpatterns = [
url(r'^$', TemplateView.as_view(template_name='pages/home.html'), name="home"),
url(r'^about/$', TemplateView.as_view(template_name='pages/about.html'), name="about"),
# Django Admin, use {% url 'admin:index' %}
url(settings.ADMIN_URL, include(admin.site.urls)),
# User management
url(r'^users/', include("contestchampion.users.urls", namespace="users")),
url(r'^accounts/', include('allauth.urls')),
# Your stuff: custom urls includes go here
# Wagtail cms
url(r'^cms/', include(wagtailadmin_urls)),
url(r'^documents/', include(wagtaildocs_urls)),
url(r'', include(wagtail_urls)),
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
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),
]
These two url confs are in conflict =
url(r'^$', TemplateView.as_view(template_name='pages/home.html'), name="home"),
url(r'', include(wagtail_urls)),
One must change, otherwise Django will always resolve the base url of `yourdomain.com/' to the first entry. One easy way to fix this is to update the second-
url(r'^content/', include(wagtail_urls)),
Now your Wagtail root page will be accessible at yourdomain.com/content.
As for mysite.com/blog/blog1/ not coming up, that Url would assume that, from your Wagtail root page, there's a page w/ slug 'blog', and then a child page of that with slug blog1. The tree structure of your Wagtail site determines the URLs by default. If you want to override that you'll have to use the RoutablePageMixin as described here.

My DJango app is responding to /static urls

Update
I figured out what was causing the stylesheets to become invisible, though I don't quite understand it all. I set DEBUG=False in settings.py to test the error handling as described in the tutorial. Somehow setting debug to false causes the static files not to be locatable. I will look further in the configs to see if I can get a clear understanding why. Until then, please feel free to answer or comment with additional info. I am still learning!
Update
I'm going through a DJango tutorial from here and I hit a roadblock. I'm up to tutorial 3 where they explain how to refactor your urls.py file when I try loading up the admin site to make sure I haven't broken it. Sure enough it looked all wierd because it was missing the stylesheets. Stylesheets are pulled from here:
http://127.0.0.1:8000/static/admin/css/base.css
When I hit that link in my browser I get the custom 404 page I configured for my app. The stylesheets were working prior but I'm not sure which change broken them. I went through my urls.py file and reverted all of the polls specific url configs to no avail. Here's my current urls.py under hellodjango (the name of my project.)
from django.conf.urls import patterns, include, url
# Uncomment the next two lines to enable the admin:
from django.contrib import admin
from django.http import HttpResponse
admin.autodiscover()
urlpatterns = patterns('',
url(r'^polls/', include('polls.urls')),
url(r'^admin/', include(admin.site.urls)),
)
def page_not_found(request, template_name='404.html'):
return HttpResponse("Could not find the resource you asked for...")
handler404 = 'hellodjango.urls.page_not_found'
and here's the urls.py under my polls directory:
from django.conf.urls import patterns, url
# Uncomment the next two lines to enable the admin:
urlpatterns = patterns('polls.views',
url(r'^$', 'index'),
url(r'^(?P<poll_id>\d+)/$', 'detail'),
url(r'^(?P<poll_id>\d+)/results/$', 'results'),
url(r'^(?P<poll_id>\d+)/vote/$', 'vote'),
)
Help?
It looks like you don't have a URL pattern for /static. As such, the static/admin/css/base.css URL doesn't match any pattern, and so you get a 404. Try something like this:
from django.conf.urls.static import static
# ...
urlpatterns = patterns('',
# ...
url(r'^static/(?P<path>.*)$', 'django.views.static.serve',
{'document_root': settings.STATIC_ROOT}),
# ...
This should work for you -- go to /static/foo.css, and you should see your CSS.
It's worth noting that this is discouraged in a production environment. For your tutorial app, though, it'll work.
The staticfiles app provides a custom runserver management command that automatically serves the static files, are you sure you have the following in your settings?
INSTALLED_APPS = (
# ...
'django.contrib.staticfiles',
)
In production, you'll use the collectstatic management command that finds all of the static media and dumps it into STATIC_ROOT (this is the only purpose for this setting - it isn't used or needed during development).
Glad you figured it out. Here's why it works like this.
django.contrib.staticfiles overrides the runserver management command so that the static files are served automatically. To remind people that they shouldn't be using django to serve static files, this only happens when DEBUG = True, as you found out.
The documentation of the overridden management command explains that you can use the --insecure flag to make this work no matter the state of the DEBUG setting.

How does Django serve media files?

I have set up a Django application that uses images. I think I have set up the media settings MEDIA_ROOT and MEDIA_URL correctly. However the images don't show up. Do you know what can be the problem?
Let consider this example:
The image files are under /home/www/media/app/photos and we are trying to request http://example.com/photos/123.jpg
Should I use these settings?
MEDIA\_ROOT = /home/www/media
MEDIA_URL = http://example.com/app
UPDATE: Forgot to mention that I'm using built-in development server.
FOR DEVELOPMENT ONLY
You can setup a static media server for use with their development server by doing this in your urls.py file. I have attached the code showing how I use it (along with the forced DEBUG conditionals.)
from django.conf import settings
from django.conf.urls.defaults import *
# Uncomment the next two lines to enable the admin:
from django.contrib import admin
admin.autodiscover()
urlpatterns = patterns('',
(r'^$', 'views.index'),
# Accounts
(r'^accounts/login/$', 'views.user_login'),
(r'^accounts/logout/$', 'views.user_logout'),
# Contrib Modules
(r'^admin/(.*)', admin.site.root),
)
if settings.DEBUG :
urlpatterns += patterns('',
(r'^media/(?P<path>.*)$', 'django.views.static.serve', {'document_root': settings.MEDIA_ROOT, 'show_indexes': True}),
)
I place my MEDIA_ROOT in a subdirectory of html/media and link to it as such in settings.py
MEDIA_ROOT = os.path.join(os.path.dirname(__file__), 'html/media/').replace('\\','/')
After development is finished, the project gets deployed to the web server where static media files are then served by Apache using directives.
Serving static content from Django is discouraged from the developer themselves (if I'm not wrong, it only works when in debug mode). You should use a dedicated web server, instead.
If you really need to do that, anyway, read the documentation on how to serve static files.
This is the correct way of showing image files with ImageField. Imagine we have a user profile picture:
models.py:
UserProfile:
profilePic= models.ImageField( upload_to='PATH_TO_UPLOAD', blank=True, null=True)
settings.py:
MEDIA_ROOT = 'FULL_PATH_OF_MEDIA'
MEDIA_URL = 'URL_OF_MEDIA'
urls.py:
urlpatterns = [
.
.
.
]+ static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
PATH_TO_UPLOAD is the path which user upload data goes. This is sub-directory of FULL_PATH_OF_MEDIA, which means the uploaded file will have
FULL_PATH_OF_MEDIA/PATH_TO_UPLOAD
full path.Now this content can be accessed at this url:
SITE_NAME/URL_OF_MEDIA/PATH_TO_UPLOAD
I also recommend reading this on static_files vs media_files
doc
You can just add those lines to your urls.py
from django.urls import re_path
from django.views.static import serve
urlpatterns = [
...
re_path(r'^media/(?P<path>.*)$', serve,{'document_root': settings.MEDIA_ROOT}),
]
I suspect you are getting the Django 404 page. Try directly accessing one of your images and see if that's happening.
If so, your need to configure your web server to not send requests within your media hierarchy to Django but to instead serve them directly. Here is a snip from my Apache conf file. The first section tells Apache to send everything to Django. The second section has "SetHandler None" which says "handle stuff under /media in the normal way."
See http://docs.djangoproject.com/en/dev/howto/deployment/modpython/ for all the exciting details.
Partial httpd.conf file for PrinceOfPinot.com (AKA pop):
<Location "/">
SetHandler python-program
PythonAutoReload Off
PythonDebug Off
PythonPath "['/var/www/production/pop', '/usr/local/lib/python2.5/site-packages/django'] + sys.path"
SetEnv DJANGO_SETTINGS_MODULE settings
PythonHandler django.core.handlers.modpython
</Location>
<Location "/media">
SetHandler None
AddOutputFilterByType DEFLATE text/html text/css application/x-javascript
</Location>
I'm aware that the original question is with the dev server, but for anyone else who is looking for a production environment answer:
https://docs.djangoproject.com/en/1.8/howto/static-files/deployment/ provides a guide on how to have django serve files in a production environment. From the tone of the guide, it does seem to imply that it is best to have a separate web server to handle the files or use mod_wsgi with Apache