Skip to main content

django-wee

PyPI - Version PyPI - Python Version

A minimal Django application for creating and resolving short URLs, backed by Sqids codes and Django's cache framework.


Table of Contents

Requirements

  • Python 3.10+
  • Django 5.2+

Installation

pip install django-wee

Add django_wee to INSTALLED_APPS and include its URL patterns:

# settings.py
INSTALLED_APPS = [
    ...
    "django_wee",
]
# urls.py
from django.urls import include, path

urlpatterns = [
    ...
    path("s/", include("django_wee.urls")),
]

Then run the migrations:

python manage.py migrate

ASGI / async projects

If your project runs under an ASGI server, use the async URL module instead:

(path("s/", include("django_wee.urls_async")),)

Configuration

No mandatory configuration is required. See Settings reference for optional tunables.

Usage

Creating short URLs

Use the provided shortcut functions anywhere in your code:

from django.urls import reverse
from django_wee.shortcuts import create_short_url

short_url = create_short_url("https://example.com/a/very/long/url")
short_path = reverse("django_wee:redirect", args=[short_url.code])
# → "/s/aBcD1234/"

Pass an optional timezone-aware expiration datetime to create a URL that stops resolving after the specified time:

from datetime import timedelta

from django.urls import reverse
from django.utils import timezone

from django_wee.shortcuts import create_short_url

expiration = timezone.now() + timedelta(days=7)
short_url = create_short_url("https://example.com/a/very/long/url", expiration=expiration)
short_path = reverse("django_wee:redirect", args=[short_url.code])

If no expiration is provided, the short URL does not expire.

Alternatively, pass a ttl (time-to-live) to compute the expiration as a offset from now. An int or float is interpreted as seconds, and a timedelta is used directly. expiration and ttl are mutually exclusive:

from datetime import timedelta

from django.urls import reverse
from django_wee.shortcuts import create_short_url

short_url = create_short_url("https://example.com/a/very/long/url", ttl=timedelta(days=7))
short_path = reverse("django_wee:redirect", args=[short_url.code])

An async variant is also available:

from datetime import timedelta

from django.urls import reverse
from django.utils import timezone

from django_wee.shortcuts import acreate_short_url

expiration = timezone.now() + timedelta(days=7)
short_url = await acreate_short_url("https://example.com/a/very/long/url", expiration=expiration)
short_path = reverse("django_wee:redirect", args=[short_url.code])

Both functions validate the URL, persist a ShortUrl record, populate the cache, and return the persisted ShortUrl instance.

URLs without a scheme are normalized to https:// before validation and persistence. For example, create_short_url("example.com") stores https://example.com. Protocol-relative URLs (//example.com) receive an https: prefix, and URLs that already include a scheme are left unchanged.

Resolving short URLs

Requests to GET /s/<code>/ are handled automatically by the redirect view. The view checks the cache first and falls back to the database. Expired short URLs are not resolved. The response type (301 or 302) is controlled by the WEE_PERMANENT_REDIRECT setting.

Deleting expired URLs

The delete_expired_short_urls management command removes expired short URLs from the database:

python manage.py delete_expired_short_urls

By default, every short URL whose expires_at timestamp is in the past is deleted. Use --older-than to restrict the deletion to URLs that have been expired for at least the given duration:

python manage.py delete_expired_short_urls --older-than "7 days"

The duration accepts any format supported by Django's parse_duration (e.g. "7 days", "12 hours", "PT30M").

Use --dry-run to preview how many URLs would be deleted without performing the deletion:

python manage.py delete_expired_short_urls --older-than "7 days" --dry-run

Settings reference

Setting Default Description
WEE_CACHE_ALIAS "default" Cache alias (from CACHES) used to store short-URL mappings.
WEE_CACHE_TIMEOUT 3600 Cache TTL in seconds.
WEE_CACHE_PREFIX "WEE" Prefix used for short-URL cache keys. Keys use the prefix:code format.
WEE_MIN_LEN 8 Minimum length of the generated Sqids code.
WEE_ALPHABET Sqids default Character set used to generate codes.
WEE_PERMANENT_REDIRECT True If True, the redirect view returns HTTP 301; otherwise HTTP 302.

License

django-wee is distributed under the terms of the MIT license.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

django_wee-0.2.1.tar.gz (16.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

django_wee-0.2.1-py3-none-any.whl (14.7 kB view details)

Uploaded Python 3

File details

Details for the file django_wee-0.2.1.tar.gz.

File metadata

  • Download URL: django_wee-0.2.1.tar.gz
  • Upload date:
  • Size: 16.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for django_wee-0.2.1.tar.gz
Algorithm Hash digest
SHA256 3df24880721d70ec806aef1915ea37c2d02c3f57f83a6e2507d4ba60dd126f35
MD5 7533f06545a830ad4815da8291fe6596
BLAKE2b-256 933e4db80be6ad094640d6a91c21bc07e77fe2a7a0cff91b37df7b61d29abdeb

See more details on using hashes here.

Provenance

The following attestation bundles were made for django_wee-0.2.1.tar.gz:

Publisher: release.yml on hartungstenio/django-wee

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file django_wee-0.2.1-py3-none-any.whl.

File metadata

  • Download URL: django_wee-0.2.1-py3-none-any.whl
  • Upload date:
  • Size: 14.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for django_wee-0.2.1-py3-none-any.whl
Algorithm Hash digest
SHA256 2e56f45b173b16e2cf0688cbb8b71d1c04b8a218ae6406843ed7fb4ea2d41092
MD5 5847c4f46df1c037c7252996bfc32dcc
BLAKE2b-256 db7b97314885bcc76e0139f9df8722d80963d5973dcdd72be19114bca76a02ba

See more details on using hashes here.

Provenance

The following attestation bundles were made for django_wee-0.2.1-py3-none-any.whl:

Publisher: release.yml on hartungstenio/django-wee

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

0.2.3

2 files

0.2.2

2 files

This release

0.2.1 This release

2 files

0.2.0

2 files

0.1.0

2 files

0.0.1

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page