Quickstart
Install these packages:
pip install pillow django-imagekit
Add these lines to the project settings.py
file:
INSTALLED_APPS = [
'blog.apps.BlogConfig',
# HERE
'imagekit',
'django.contrib.admin',
'django.contrib.auth',
# ...
]
# START
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
# END
Add these fields to a model:
from django.db import models
from imagekit.models import ImageSpecField
from pilkit.processors import Thumbnail
class Post(models.Model):
image = models.ImageField(upload_to='images')
image_medium = ImageSpecField(source='image',
processors=[Thumbnail(200, 100)],
format='JPEG',
options={'quality': 60})
image_small = ImageSpecField(source='image',
processors=[Thumbnail(100, 50)],
format='JPEG',
options={'quality': 60})
slug = models.SlugField(max_length=255, unique=True)
Output image URLs in templates like this:
<img src="{{ post.image_medium.url }}">
<img src="{{ post.image_small.url }}">
<img src="{{ post.image.url }}">
Full Tutorial
Run these commands to setup a new project:
python3 -m venv venv && \
source venv/bin/activate && \
pip install --upgrade pip && \
pip install django pillow django-imagekit && \
django-admin startproject mysite . && \
python manage.py startapp blog && \
python manage.py createsuperuser
- The
django-imagekit
package adds image processing functionality to our project. It requires thepillow
imaging library to work.
Edit the project settings.py
file and add these lines to it:
INSTALLED_APPS = [
# START
'blog.apps.BlogConfig',
'imagekit',
# END
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
]
# START
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
# END
- The
MEDIA_URL
setting defines the base URL for serving user uploaded files. - The
MEDIA_ROOT
setting defines the physical location where the files are stored in the system. In this case the files are stored in the project rootmedia
directory.
Post model
Edit the blog app models.py
file and add these lines to it:
from django.db import models
from imagekit.models import ImageSpecField
from pilkit.processors import Thumbnail
class Post(models.Model):
image = models.ImageField(upload_to='images')
image_medium = ImageSpecField(source='image',
processors=[Thumbnail(200, 100)],
format='JPEG',
options={'quality': 60})
image_small = ImageSpecField(source='image',
processors=[Thumbnail(100, 50)],
format='JPEG',
options={'quality': 60})
slug = models.SlugField(max_length=255, unique=True)
- The
ImageSpecField
field specifes an image spec that generates new images from a source field. In this case from theimage
field. You can pass it bunch of parameters that defines how the image is generated. - The
Thumbnail
processor creates a thumbnail and tries to be smart about how it crops it.
The processors are imported from PILKit utilities.
python manage.py makemigrations && \
python manage.py migrate
Edit the blog app admin.py
file and add these lines to it:
from django.contrib import admin
from blog.models import Post
admin.site.register(Post)
URLs
Edit the project urls.py
file and add these lines to it:
from django.contrib import admin
from django.urls import path
# START
from django.conf.urls.static import static
from django.conf import settings
from blog.views import PostDetailView
# END
urlpatterns = [
# HERE
path('blog/<slug:slug>/',
PostDetailView.as_view(),
name='post_detail'),
path('admin/', admin.site.urls),
# HERE
] + static(settings.MEDIA_URL,
document_root=settings.MEDIA_ROOT)
PostDetailView
Edit the blog app views.py
file and add these lines to it:
from django.views.generic import DetailView
from blog.models import Post
class PostDetailView(DetailView):
model = Post
Template
Create a file called post_detail.html
in the blog/templates/blog
directory. Add these lines to it:
{% if post.image %}
<img src="{{ post.image_medium.url }}">
<img src="{{ post.image_small.url }}">
{% endif %}
- The
PostDetailView
view uses a template namedpost_detail.html
automatically without us having to specify it. - The thumbnails are generated when you first visit the detail page.
Visit /admin/
to create a new blog post:
Visit /blog/django-tutorial/
and you should see something like this:
You can access the original image with {{ post.image.url }}
.
Images are served from the media
folder:
media/static/images/05.jpg
Its thumbnails are served from the CACHE
subdirectory:
media/CACHE/static/images/static/images/05/9bba...22ce9e.jpg