Сокращенные URL для модельных объектов в Django

Требуется, чтобы URL вида https://example.com/projects/last_year/jane/great-finance-2020/ открывался по адресу наподобие https://example.com/4xct4/ (с перенаправлением), без хранения идентификатора сокращения, т. е. с декодированием по алгоритму.

Алгоритм

Воспользуемся модулем short_url. На простейшем уровне short_url использует алгоритм для преобразования любого числа в последовательность букв. Алгоритм является детерминированным, что означает, что каждый раз, когда вы кодируете одно и то же значение, вы получаете один и тот же результат:

>>> import short_url
>>> url = short_url.encode_url(12)
>>> print url
LhKA
>>> key = short_url.decode_url(url)
>>> print key
12

Еще один приятный аспект — некоторые буквы и цифры исключаются во избежание путаницы, например, 0 или O.

Создание представления

views.py:

from django.apps import apps
from django.http import Http404
from django.shortcuts import get_object_or_404, redirect

import short_url


def redirect_view(request, tiny):
    """
    Redirect to a given object from a short URL.
    """

    model = apps.get_model('MY_PROJECT', 'MY_APP')
    try:
        id = short_url.decode_url(tiny)
    except ValueError:
        raise Http404('Bad encoded ID.')

    obj = get_object_or_404(model, pk=id)
    return redirect(obj)

Связывание представления и URL

urls.py:

from django.urls import path

from .views import redirect_view

urlpatterns = [path('<slug:tiny>/', view=redirect_view, name='shortener')]

Формирования короткого URL для объекта

models.py:

def get_short_url(self):
    """
    A way to generate a short_url.
    """

    tinyid = short_url.encode_url(self.pk)
    return reverse_lazy('shortener', kwargs={'tiny': tinyid})