Writing Your Shortener URL

    image

    The article describes how to create a simple sokraschalki links, like bit.ly or goo.gl .



    So, we go into the directory with your project and create the application. Let it be called 'shortener' .
    $ django-project startapp shortener

    First, let’s describe a simple URL configuration that will determine what the user needs in accordance with his request.


    # urls.py 
    from
    django.conf.urls.defaults import *
     
    urlpatterns = patterns ('',
       (r '^ $', 'views.index'),
       (r '^ (? P. {3}) $ ',' views.redirect '),
    )

    We will consider the case when the address example.com is used for reduction, that is, the above configuration is the only one (do not forget to specify ROOT_URLCONF in settings.py). If you use an address like example.com/shortener/, do not forget to connect your configuration to the main one using the include mechanism .

    Now, when accessing example.com, it will call the index submission function from the views.py file , the rest of the addresses, the length of which is 3 three characters (without a domain), we will try to “expand” using the redirect functionfrom the same file. To shorten the links, we will use Latin letters in different cases and numbers. The length of the "key" will be three characters, this is quite enough for not very mass services (62 ^ 3 options).

    Our next step will be to determine the model, that is, a description of the data at the database level.

    # models.py 
    from django.db import models
     
    from datetime import datetime
    from random import choice
    import string
     
     
    def generate_key():
            chars = string.digits + string.letters
            return ''.join(choice(chars) for _ in range(3))
     
    class ShortUrl(models.Model):
     
        key = models.CharField(max_length=3, primary_key=True, default=generate_key)
        target = models.URLField(verify_exists=False, unique=True)
        added = models.DateTimeField(auto_now_add=True, editable=False)
     
        def __unicode__(self):
            return '%s  %s' % (self.target, self.key)
     
     
    class Hit(models.Model):
     
        target = models.ForeignKey(ShortUrl)
        time = models.DateTimeField(auto_now_add=True, editable=False)
        referer = models.URLField(blank=True, verify_exists=False)
        ip = models.IPAddressField(blank=True)
        user_agent = models.CharField(blank=True, max_length=100)

    After importing the necessary functions and models, we implement a function that will generate a random key from the given characters. The following describes the ShortUrl class , which is responsible for representing our shortened link in the database. Each object of this class has a unique key attribute , a field in which the "long" link is stored, as well as the date the link was created. Then comes the class Hit . Using it, we will store information about the click on the shortened link, namely the time of the click, the IP of the clicker, his User Agent and Referer , and of the “long” link.

    Pay attention to the arguments of the fields, later they will be very important.

    Our page, on which the user can shorten his link, will be very minimalistic - one form and one button (it is shown in the first picture). Let's describe this small form, its code will be contained in forms.py .

    #forms.py
    from django import forms
     
    class UrlForm(forms.Form): 
        url = forms.URLField(label='url', verify_exists=False)

    Everything is very simple here - one field, with the help of which we will process the “long” link sent by the user.

    It's time to write a view that will process the data passed by our URL configuration . First we describe the make_short_url function and import the necessary modules and functions.

    #views.py
    from django.http import HttpResponseRedirect
    from django.shortcuts import render_to_response, get_object_or_404
    from django.template import RequestContext
     
    from forms import UrlForm
    from models import ShortUrl, Hit
     
     
    def make_short_url(url):
        short_url = ShortUrl.objects.get_or_create(target=url)[0]
        short_url.save()
        return 'http://example.com/%s' % (short_url.key)

    After imports, a function is implemented that takes a certain link, creates a corresponding object of the ShortUrl class and returns an already shortened link (it was generated during the creation of the object). You can also use Site.objects.get_current (). Domain from django.contrib.sites.models .

    Now we need to write functions that process the form and implement the deployment of a “short” link, that is, a redirect.

    #views.py (continuation)
    def index(request):
        if request.method == 'POST':
            form = UrlForm(request.POST)
            if form.is_valid():
                url = form.cleaned_data.get('url')
                url = make_short_url(url)
                return render_to_response('shortener.html', {'url':url})
        else:
            form = UrlForm(label_suffix='')
        return render_to_response('shortener.html', {'form': form, 'url': ''})
     
     
    def redirect(request, key):
        target = get_object_or_404(ShortUrl, key=key)
     
        try:
            hit = Hit()
            hit.target = target
            hit.referer = request.META.get("HTTP_REFERER", "")
            hit.ip = request.META.get("REMOTE_ADDR", "")
            hit.user_agent = request.META.get("HTTP_USER_AGENT", "")
            hit.save()
        except IntegrityError:
            pass
     
        return HttpResponseRedirect(target.target)

    The index function displays an empty form if the user has not yet accessed it, and processes it in case of a POST request. In the first case , the form shortener.html , which is responsible for the interface, is passed the form itself and an empty link, in the second - only a shortened link. This is followed by the redirect function , which is referred to by the URL configuration if it considers the user's request for a request to deploy a “short” link. Before a simple redirect, we create an object of the Hit class described in models.py with the corresponding attributes obtained from the request object. I also advise you to read the comments, they have a lot of interesting things about the “except: pass” construction.

    It remains just a little bit, a little more and we will have our own shortener links!

    The time has come to describe our shortener.html template , which is responsible for the HTML representation of the form and the shortened link. Remember what parameters it takes.


    {% if not url %}
        

            {{ form.as_p }}
             
        

    {% else %}
            {{ url }}
    {% endif %}

    Basically, you can already use this code - the Shortener URL itself has already been created. It remains to describe the presentation of our data in the admin interface (do not forget to connect the appropriate configuration in the urls.py file ).

    #admin.py
    from django.contrib import admin
     
    from models import ShortUrl, Hit
     
     
    class ShortUrlAdmin(admin.ModelAdmin):
        fields = ('target', 'key')
        list_display = ('key', 'target', 'added')
        ordering = ('-added',)
        list_filter = ('added',)
        date_hierarchy = 'added'
     
    admin.site.register(ShortUrl, ShortUrlAdmin)
     
     
    class HitAdmin(admin.ModelAdmin):
        list_display = ('target', 'ip', 'user_agent', 'referer', 'time')
        ordering = ('-time',)
        list_filter = ('target', 'referer', 'time')
        date_hierarchy = 'time'
     
    admin.site.register(Hit, HitAdmin)

    That's all. Left to execute
    $ python manage.py syncdb

    And enjoy the result :)

    Admin interface:

    image

    image

    The result of our URL Shortener'a:

    image

    You can try it here .

    Also popular now: