Last active
August 9, 2021 04:03
-
-
Save Wolemercy/3079bf61211a3cc528f24bf4ea86fe40 to your computer and use it in GitHub Desktop.
Django Model for URL Shortener Application
This file contains hidden or 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
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) |
This file contains hidden or 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
""" | |
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',) |
This file contains hidden or 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
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) |
This file contains hidden or 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
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 |
This file contains hidden or 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
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