- Author:
- matt.geek.nz
- Posted:
- February 13, 2009
- Language:
- Python
- Version:
- 1.0
- Score:
- 2 (after 2 ratings)
This allows you to host your own URL shortening service for your site's internal urls. By adding this class as a Mixin to your models, any model with a get_absolute_url method will have a get_short_url method also, which either returns an existing redirect or creates a new one and returns that.
Usage:
Import the class above, add the mixin to your model declaration, and ensure you have declared a get_absolute_url method.
class MyModel = (models.Model, ShortURL):
Pre-requisites:
You must have the django.contrib.redirects app installed, and you must be using the RedirectFallbackMiddleware as a middleware class.
Settings:
Change the settings in the code above or set them in your settings.py file
SHORTURL_CHARS: the characters to use when creating a shorturl
SHORTURL_CHAR_NO = the number of characters to use in a shorturl
SHORTURL_APPEND_SLASH = whether to append a slash to the end of the shorturl redirect
Notes:
The default settings will give you about 17 million different unique short URLs, reducing the number of characters used to 4 will give you 600,000 or so. That's enough that collisions will be quite rare for sites of a few thousand pages (collisions just result in a urls being generated until an unused combination is found) but if you've got a big site you'll probably want to explore a more robust solution with a proper hash function.
http://matt.geek.nz/blog/text/generating-short-urls-django-site-urls/
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 | from django.conf import settings
from django.contrib.sites.models import Site
from django.contrib.redirects.models import Redirect
from random import choice, seed
from os import urandom
SHORTURL_CHARS = getattr(settings, "SHORTURL_CHARS", "bcdfghjklmnpqrstvwxyz2346789")
SHORTURL_CHAR_NO = getattr(settings, "SHORTURL_CHAR_NO", 5)
SHORTURL_APPEND_SLASH = getattr(settings, "SHORTURL_APPEND_SLASH", True)
class ShortURLException: pass
class ShortURL(object):
"""
A mixin that sets up short url redirects for models that have a get_absolute_url
method. Requires django.contrib.redirects to be installed to create redirects, and
django.contrib.redirects.middleware.RedirectFallbackMiddleware to use them.
"""
def __init__(self, *args, **kwargs):
"""
Seeds randomiser
"""
seed(urandom(256))
super(ShortURL, self, *args, **kwargs)
def get_short_url(self, *args, **kwargs):
"""
Finds the short url for the object's absolute url in the Redirects model objects.
If it doesn't exist, generate a short url and create a new Redirect object.
"""
if not hasattr(self, 'get_absolute_url'):
return None
else:
currenturl = self.get_absolute_url()
site = Site.objects.get(id=settings.SITE_ID)
redirects = Redirect.objects.filter(site=site, new_path=currenturl)
for url in redirects:
if len(url.old_path) <= SHORTURL_CHAR_NO + 1: #allow for leading slash
shorturl = url.old_path
break
else:
shorturl = None
if not shorturl:
# Check we've got at least a 9 in ten chance of not colliding or throw an exception
if Redirect.objects.count() > (len(SHORTURL_CHARS) ** SHORTURL_CHAR_NO) / 10:
raise ShortURLException
while True:
shorturl = '/'+''.join([choice(SHORTURL_CHARS) for char in range(SHORTURL_CHAR_NO)])
if not Redirect.objects.filter(site=site, old_path=shorturl):
# save shorturl without trailing slash so redirect middleware will find both forms
r = Redirect(site=site, old_path=shorturl, new_path=currenturl)
r.save()
break
shorturl += '/' if SHORTURL_APPEND_SLASH else ''
return shorturl
|
More like this
- Template tag - list punctuation for a list of items by shapiromatron 11 months, 2 weeks ago
- JSONRequestMiddleware adds a .json() method to your HttpRequests by cdcarter 11 months, 3 weeks ago
- Serializer factory with Django Rest Framework by julio 1 year, 6 months ago
- Image compression before saving the new model / work with JPG, PNG by Schleidens 1 year, 7 months ago
- Help text hyperlinks by sa2812 1 year, 7 months ago
Comments
I made some changes on the 16th of February to address a couple of bugs.
#
Please login first before commenting.