问题
I've finish my first app in Django and works perfectly, but still have pre-deployment problems since I set DEGUG=False ... Here is just to display an image in a template... T_T
I was using this, but now it does'nt work when I use whitenoise to serve my image localy... And it return a Bad Request(400) error...
Models.py
class GalleryItem(models.Model):
thumbnail = models.ImageField(blank=True,upload_to='gallery/thumb')
img_wide = models.ImageField(blank=True,upload_to='gallery')
template.py
{% load staticfiles %}
{% for img in img_to_display %}
<a href="{{ img.img_wide.url}}" class="swipebox" title="">
<img src="{% static img.thumbnail.url %}" alt="{{ img.alt}}">
</a>
{% endfor %}
urls.py
from django.conf.urls import url, include
from django.contrib import admin
from django.conf import settings
import os
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = [
url(r'^gallery/', include('gallery.urls')),
url(r'^shop/', include('shop.urls')),
url(r'^events/', include('events.urls')),
url(r'^page/', include('paginator.urls')),
url(r'^news/', include('blog.urls')),
url(r'^ckeditor/', include('ckeditor_uploader.urls')),
url(r'^admin/', admin.site.urls),
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
settings.py
import os
import dj_database_url
BASE_DIR = os.path.dirname(os.path.dirname(__file__))
print("BASE_DIR = ",BASE_DIR)
MEDIA_ROOT = os.path.join(BASE_DIR, 'wt/static/media/')
MEDIA_URL = '/media/'
SECRET_KEY = 'SECRET_KEY'
DEBUG = False
INSTALLED_APPS = [
'ckeditor',
'ckeditor_uploader',
'team.apps.TeamConfig',
'gallery.apps.GalleryConfig',
'shop.apps.ShopConfig',
'events.apps.EventsConfig',
'blog.apps.BlogConfig',
'paginator.apps.paginatorConfig',
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
]
MIDDLEWARE_CLASSES = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'whitenoise.middleware.WhiteNoiseMiddleware',
]
ROOT_URLCONF = 'wt.urls'
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR, 'templates')],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
"django.contrib.auth.context_processors.auth",
"django.core.context_processors.request",
"django.core.context_processors.debug",
"django.core.context_processors.i18n",
"django.core.context_processors.media",
"django.core.context_processors.static",
"django.core.context_processors.tz",
"django.contrib.messages.context_processors.messages",
],
},
},
]
WSGI_APPLICATION = 'wt.wsgi.application'
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql',
'NAME': 'wt_db',
'USER': 'postgres',
'PASSWORD': 'PASSWORD',
'HOST': '127.0.0.1',
'PORT': '5432',
}
}
AUTH_PASSWORD_VALIDATORS = [
{
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
},
]
LANGUAGE_CODE = 'fr-fr'
TIME_ZONE = 'UTC'
USE_I18N = True
USE_L10N = True
USE_TZ = True
db_from_env = dj_database_url.config(conn_max_age=500)
DATABASES['default'].update(db_from_env)
ALLOWED_HOSTS = ['localhost', '127.0.0.1',]
STATIC_ROOT = os.path.join(BASE_DIR, 'wt/staticfiles')
STATIC_URL = '/static/'
STATICFILES_DIRS = [
os.path.join(BASE_DIR, 'wt/static'),
os.path.join(BASE_DIR, 'wt/staticfiles'),
]
STATICFILES_STORAGE = 'whitenoise.django.GzipManifestStaticFilesStorage'
CKEDITOR_UPLOAD_PATH = 'uploads'
CKEDITOR_IMAGE_BACKEND = 'pillow'
CKEDITOR_BROWSE_SHOW_DIRS = True
Here my error log :
The joined path (E:\media\gallery\thumb\lost-thumb.jpg) is located outside of the base path component (E:\dev\wt\wt\wt\staticfiles)
[15/May/2016 20:01:41] "GET /page/gallery HTTP/1.1" 400 26
Thanks a lot for helping ! :)
EDIT :
principal structure
project folder
回答1:
Bro, you cant load staticfile when you use images on models, there is 2 different ways to work with images in django.
Statics files is for files that are static(images files like logo of your company, banners, javascript files, css files)
Media Files is for dinamic files like user photo, user gallery, product images
- Static Files - This way you use your staticfiles save at your static folder where you place it in static root at your settings.py and then you use {% load staticfiles %} and {% static '' %}
- Media Files - This files is that one you save with your models, ImageField, FileField and etc... that one you do not load as static, cuz they are not a static file (you can edit it from your models), that do not means you will save it on your database, this will generate a copy of your file with hashed name on it at you media folder where you place it in media root at your settings.py and media files you use like that {{ ..url }} so in your case gallery.thumbnail.url (btw, remind to call your gallery object at your views and send it to template to allow your to use it)
So the other anwers was right, you need to decide what you want to use, keep in mind that your path localy is different where you deploy, remember to use environment variables with the right path to set up in your settings
Django Docs: https://docs.djangoproject.com/en/1.11/topics/files/
回答2:
I gess it was a security issue. Even if "whitenoise" is good to serve true static files in production, it can't serve media files.
I was making a structure error :
# Don't place your 'media' files IN your 'static' file like this :
MEDIA_ROOT = os.path.join(BASE_DIR, 'wt/static/media/')
MEDIA_ROOT never have to be in the "static" file of your project (even if you can make it works in some ways, it's not a good practice I think).
'MEDIA' files (in production), have to be serve out of the Django project. I've read somewhere that we have to use a CDN. And firstly I choose CloudFlare (because it's free), but it wasn't working, cause you need a subdomain/hostname to point your MEDIA_ROOT, and CloudFlare doesn't give that. Finaly I choose Amazon S3.
So, in conclusion write something like {% static img.thumbnail.url %}
make no sense. Because everything uploaded via admin/user haven't to be in "static".
Use {{ img.thumbnail.url }}
instead.
回答3:
Try <img src="{{ img.thumbnail.image.url }}" alt="{{ img.alt}}">
来源:https://stackoverflow.com/questions/37241902/django-joined-path-is-located-outside-of-the-base-path-component-static-img