Last active
May 12, 2017 11:39
-
-
Save sivaa/df6442799248bdbb0bb5 to your computer and use it in GitHub Desktop.
Thin Django - Guide
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
############ 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