Skip to content

Instantly share code, notes, and snippets.

@sivaa
Last active May 12, 2017 11:39
Show Gist options
  • Save sivaa/df6442799248bdbb0bb5 to your computer and use it in GitHub Desktop.
Save sivaa/df6442799248bdbb0bb5 to your computer and use it in GitHub Desktop.
Thin Django - Guide
############ Part 0 - Prerequistes #############
# Step 1 : Setup your virtual environment
# Step 2 : Install the required dependencies
$ pip install django
$ pip install gunicorn
$ pip install PIL (For Windows : easy_install PIL)
# Step 3 : Create thin/thin.py
############ Part 1 - Thin Django #############
# Step 1 : Write the basic view
from django.http.response import HttpResponse
## Views
def home(request):
return HttpResponse("Hello Django!")
# Step 2 : Add the URL routing
from django.conf.urls import url
# Routing
urlpatterns = (
url(r'^$', home, name='home'),
)
# Step 3 : Configured the project settings
from django.conf import settings
# Settings
settings.configure(
ROOT_URLCONF = __name__,
)
# Step 4 : Configure the entry point and execution
import sys
from django.core.management import execute_from_command_line
# Execution
if __name__ == '__main__':
execute_from_command_line(sys.argv)
# Step 5 : Run the development server
$ python thin.py runserver
# It will fail and fix the error by adding DEBUG in the settings
settings.configure(
DEBUG = True,
ROOT_URLCONF = __name__,
)
# Run the server again
$ python thin.py runserver
# Verify the results in the browser
http://localhost:8000/
############ Part 1 - Create Thin Django Template #############
# Step 1 : Make it WGSI compatible
from django.core.wsgi import get_wsgi_application
application = get_wsgi_application()
# Step 2 : [OPTIONAL]Run it with Gunicorn(Works in Linux Only)
$ gunicorn thin.py --log-file=-
# Step 3 : Enhance the DEBUG setting to read it from environment variable
import os
DEBUG = os.environ.get('DEBUG', 'on') == 'on',
# Run the development server and test it
# Set the DEBUG environment variable to off
$ set DEBUG=off # Windows
$ export DEBUG=off # Linux
# Run the development server and test it
# Fix the error by adding ALLOWED_HOST settings
ALLOWED_HOSTS = os.environ.get('ALLOWED_HOSTS', 'localhost').split(","),
# Run the development server and test it using http://localhost:8000/
# Run the development server and test it using http://127.0.0.1:8000/
# Fix it by setting the ALLOWED_HOSTS environment variable to 127.0.0.1
$ set ALLOWED_HOSTS=127.0.0.1
# Run the development server and test it using http://127.0.0.1:8000/
# Run the development server and test it using http://localhost:8000/
# Fix it by setting the ALLOWED_HOSTS environment variable to 127.0.0.1
$ set ALLOWED_HOSTS=127.0.0.1,localhost
# Unset the DEBUG environment variable
$ set DEBUG= # Windows
$ unset DEBUG # Linux
# Run the development server and test it using http://127.0.0.1:8000/
# Run the development server and test it using http://localhost:8000/
# Step 4 : Configure the SECERT_KEY setting to read it from environment variable
SECERT_KEY = os.environ.get('SECERT_KEY', os.urandom(32)),
# Step 5 : Configure the MIDDLEWARE_CLASSES settings
MIDDLEWARE_CLASSES = (
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
),
# Step 6 : Make this project as a template for startproject
# Update SECERT_KEY settings
SECERT_KEY = os.environ.get('SECERT_KEY', '{{ secert_key }}'),
# Update home view
def home(request):
return HttpResponse("Hello {{ project_name }}!")
# Copy/Rename the project folder and python module to project_name. It should look like this
thin/thin.py ==> project_name/project_name.py
############ Part 3 - Sample Project using Thin Django Template - Images with Water Mark #############
# Step 1 : Create a Django project called 'wm_image' from the thin template
<ENV_PATH>/django-admin.exe startproject wm_image --template=project_name
# Step 2 : Run the development server and test it
$ python wm_image.py runserver
# Step 3 : Create home page (index.html)
# Configure the templates directory in settings
BASE_DIR = os.path.dirname(__file__)
TEMPLATE_DIRS = (
os.path.join(BASE_DIR, "templates"),
),
# Create templates directory and index.html inside it (wm_image/templates/index.html)
<!DOCTYPE html>
<html>
<head>
<title> Thin Django - Images with Water Mark </title>
</head>
<body>
<h1> Images with Water Mark </h1>
</body>
</html>
# Step 4 : Enhance the home page view
from django.shortcuts import render
def home(request):
return render(request, "index.html")
# Run the development server and test it
# Step 5 : Define the URL Routing for water mark images
# Routing
urlpatterns = (
url(r'^image/(?P<image_url>.*)/(?P<water_mark_text>.*)/$', water_mark_image, name='water_mark_image'),
url(r'^$', home, name='home'),
)
# Step 6 : Create dummy 'water_mark_image' view
def water_mark_image(request, image_url, water_mark_text):
return HttpResponse("<Image>")
# Step 7 : Enhance the <body> of index.html to render the images with water mark
<img src=" {% url 'water_mark_image' water_mark_text='Company ABC' image_url='<Image URL>' %} "/>
<img src=" {% url 'water_mark_image' water_mark_text='Company ABC' image_url='http://static.guim.co.uk/sys-images/Guardian/Pix/pictures/2013/1/9/1357751342331/DJANGO-UNCHAINED-008.jpg' %} "/>
# Run the development server and test it
# Step 8 : Implement ImageForm to handle the validations
from django import forms
## Forms
class ImageForm(forms.Form):
image_url = forms.URLField()
water_mark_text = forms.CharField(min_length=3)
# Step 9 : Use the form inside the 'water_mark_image' view
def water_mark_image(request, image_url, water_mark_text):
image_form = ImageForm({'image_url' : image_url,
'water_mark_text' : water_mark_text
})
if image_form.is_valid() is False:
return HttpResponseBadRequest("Invalid Data Supplied.")
return HttpResponse("<Image>")
# Step 10 : Test the form validations using some invalid data for image_url and water_mark_text
<img src=" {% url 'water_mark_image' water_mark_text='Company ABC' image_url='dummy' %} "/>
<img src=" {% url 'water_mark_image' water_mark_text='BC' image_url='http://static.guim.co.uk/sys-images/Guardian/Pix/pictures/2013/1/9/1357751342331/DJANGO-UNCHAINED-008.jpg' %} "/>
# Step 11 : Add a method to generate the water marker image in ImageForm
def add_water_mark(self):
image_url = self.cleaned_data['image_url']
water_mark_text = self.cleaned_data['water_mark_text']
# Step 12 : Enhance the 'water_mark_image' view to use 'add_water_mark' method from ImageForm
if image_form.is_valid() is False:
return HttpResponseBadRequest("Invalid Data Supplied.")
image = image_form.add_water_mark()
return HttpResponse(image, content_type='image/png')
# Step 13 : Download and save the given Image URL in the 'add_water_mark'
# Create images folder to save the downloaded images (wm_image/images)
import urllib
import hashlib
# Download the image from image_url
image_key = hashlib.sha224(image_url).hexdigest()
image_location = os.path.join('images', image_key)
with open(image_location, 'wb') as fp:
fp.write(urllib.urlopen(image_url).read())
# Step 14 : Write the given water mark text on the image
# easy_install pil (Windows) or pip install pil (Linux)
from _io import BytesIO
import Image
import ImageDraw
image_content = Image.open(image_location)
draw = ImageDraw.Draw(image_content)
draw.text((100, 100), water_mark_text, (255, 0 , 0))
content = BytesIO()
image_content.save(content, "PNG")
content.seek(0)
return content
# Run the development server and test it
# Step 15 : Add few more water marked images (same image with different text)
<img src=" {% url 'water_mark_image' water_mark_text='Company MNO' image_url='http://static.guim.co.uk/sys-images/Guardian/Pix/pictures/2013/1/9/1357751342331/DJANGO-UNCHAINED-008.jpg' %} "/>
<img src=" {% url 'water_mark_image' water_mark_text='Company XYZ' image_url='http://static.guim.co.uk/sys-images/Guardian/Pix/pictures/2013/1/9/1357751342331/DJANGO-UNCHAINED-008.jpg' %} "/>
# Run the development server and test it
# Step 16 : Use cache to avoid duplicate downloads
from django.core.cache import cache
# Download the image from image_url
image_key = hashlib.sha224(image_url).hexdigest()
# Check in cache
image_location = cache.get(image_key)
if image_location is None:
print "Not found in Cache", water_mark_text, image_url
image_location = os.path.join('images', image_key)
with open(image_location, 'wb') as fp:
fp.write(urllib.urlopen(image_url).read())
cache.set(image_key, image_location)
else :
print "Found in Cache", water_mark_text, image_url
# Run the development server and fix the error by
# Moving the settings to the top
# Import the cache after settings
# Settings
BASE_DIR = os.path.dirname(__file__)
settings.configure(
DEBUG = os.environ.get('DEBUG', 'on') == 'on',
ALLOWED_HOSTS = os.environ.get('ALLOWED_HOSTS', 'localhost').split(","),
SECERT_KEY = os.environ.get('SECERT_KEY', ''),
ROOT_URLCONF = __name__,
MIDDLEWARE_CLASSES = (
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
),
TEMPLATE_DIRS = (
os.path.join(BASE_DIR, "templates"),
),
)
from django.core.cache import cache
## Forms
class ImageForm(forms.Form):
# Run the development server and test it
# Step 17 : Implement ETAGs to cache in the middleware level
from django.views.decorators.http import etag
def etag_water_mark_image(request, image_url, water_mark_text):
wm_key = "WM : {} : {}".format(image_url, water_mark_text)
return hashlib.sha224(wm_key.encode('utf-8')).hexdigest()
@etag(etag_water_mark_image)
def water_mark_image(request, image_url, water_mark_text):
print "ETAG NOT HIT", water_mark_text, image_url
# Remove the print statements from ImageForm
# Run the development server and test it
# Step 18 : Add different images and test the etag and cache content
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment