Skip to content

Instantly share code, notes, and snippets.

@Wolemercy
Last active August 9, 2021 04:03
Show Gist options
  • Save Wolemercy/3079bf61211a3cc528f24bf4ea86fe40 to your computer and use it in GitHub Desktop.
Save Wolemercy/3079bf61211a3cc528f24bf4ea86fe40 to your computer and use it in GitHub Desktop.
Django Model for URL Shortener Application
from django.db import models
from .urlreduce_utils import create_shortened_url
# Create your models here.
class Shortener(models.Model):
'''
This model creates a short url using the long url as the input
created -> time and date the shortener was created
times_followed = the number of times the shortened link has been followed
short_url -> the shortened url
long_url -> the original link
'''
created = models.DateTimeField(auto_now_add=True)
times_followed = models.PositiveIntegerField(default=0)
long_url = models.URLField()
short_url = models.CharField(max_length=15, unique=True, blank=True)
class Meta:
ordering = ["-created"]
def __str__(self):
return f'{self.long_url} shortened to {self.short_url}'
def save(self, *args, **kwargs):
if not self.short_url:
self.short_url = create_shortened_url(self)
super().save(*args, **kwargs)
"""
Creating shortener forms
"""
from django import forms
from . import models
class ShortenerForm(forms.ModelForm):
long_url = forms.URLField(widget=forms.URLInput(
attrs={"class": "form-control", "placeholder": "Input the URL you want shortened"}
))
class Meta:
model = models.Shortener
fields = ('long_url',)
from django.test import TestCase, SimpleTestCase
from django.http import HttpRequest
from django.urls import reverse
from urlreduce.forms import ShortenerForm
class ShortenerFormTest(TestCase):
def test_form_is_valid(self):
form_data = {'long_url': 'https://developer.mozilla.org/en-US/docs/Learn/Server-side/Django/Testing'}
form = ShortenerForm(data=form_data)
self.assertTrue(form.is_valid(), form.errors)
def test_form_is_invalid(self):
form_data = {'long_url':'yada'}
form = ShortenerForm(data=form_data)
self.assertFalse(form.is_valid(), form.errors)
from django.conf import settings
from random import choice
from string import ascii_letters, digits
SIZE = getattr(settings, "MAXIMUM_URL_CHARS", 6)
AVAILABLE_CHARS = ascii_letters + digits
def create_random_code(chars=AVAILABLE_CHARS):
"""
Creates a random string of length SIZE
"""
return "".join(
[choice(chars) for _ in range(SIZE)]
)
def create_shortened_url(model_instance):
"""
Ensures random code is unique
"""
random_code = create_random_code()
curr_long_url = model_instance.long_url
#get the model class
model_class = model_instance.__class__
if model_class.objects.filter(short_url=random_code).exists():
#rerun the function
return create_shortened_url(model_instance)
return random_code
from django.shortcuts import render, get_object_or_404
from django.http import HttpResponse, Http404, HttpResponseRedirect
from .forms import ShortenerForm
from .models import Shortener
def home_view(request):
template = 'urlreduce/home.html'
context = {}
#Empty form
context['form'] = ShortenerForm()
if request.method == 'GET':
return render(request, template, context)
elif request.method == 'POST':
used_form = ShortenerForm(request.POST)
test_url = request.POST.get('long_url')
if used_form.is_valid():
try:
shortened_object = Shortener.objects.get(long_url=test_url)
context['times_followed'] = shortened_object.times_followed
except:
shortened_object = used_form.save()
new_url = request.build_absolute_uri('/') + shortened_object.short_url
long_url = shortened_object.long_url
context['new_url'] = new_url
context['long_url'] = long_url
return render(request, template, context)
context['errors'] = used_form.errors
return render(request, template, context)
def redirect_url_view(request, shortened_url):
try:
shortener = Shortener.objects.get(short_url=shortened_url)
shortener.times_followed += 1
shortener.save()
return HttpResponseRedirect(shortener.long_url)
except:
raise Http404('Ouch! This link is broken')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment