django-hashtag 
GitHub

Test

Check Demo Project
- Check the demo repo on GitHub
Requirements
- Python 3.9, 3.10, 3.11, 3.12, 3.13, 3.14 supported.
- Django 3.2, 4.2 and 5.2 supported.
We highly recommend and only officially support the latest patch release of each Python and Django series.
Setup
- Install from pip:
pip install django-hashtag
- Modify
settings.pyby adding the app toINSTALLED_APPS:
INSTALLED_APPS = [
# ...
"taggit",
"hashtag",
# ...
]
- Execute Django's command
migrateinside your project's root:
python manage.py migrate
Running migrations:
Applying hashtag.0001_initial... OK
Applying hashtag.0002_alter_mytag_slug... OK
Applying hashtag.0003_alter_mytag_last_used... OK
Usage
django-hashtag provides the tag data model plus reusable, consumer-agnostic
helpers so every site renders and filters tags the same way without
re-implementing the markup or the queryset logic.
Render tags as chips (hashtag_chips)
The hashtag_chips inclusion tag renders a tag collection as accessible chips.
It accepts model instances (exposing name/slug/get_absolute_url) or plain
strings.
{% load hashtag_tags %}
{# Static, non-linkable chips (e.g. a homepage badge row) #}
{% hashtag_chips tags variant="home" linkable=False %}
{# In-context filter links: builds <filter_url>?<filter_param>=<slug> #}
{% hashtag_chips tags variant="review" filter_url=request.path filter_param="tag" %}
{# Custom href pattern with a {slug} placeholder #}
{% hashtag_chips tags href_pattern="/reviews/?tag={slug}" %}
Arguments:
| Argument | Default | Description |
|---|---|---|
tags |
— | Iterable of tag instances or strings. |
variant |
"" |
Theme modifier; adds hashtag-chips--<variant> / hashtag-chip--<variant>. |
linkable |
True |
When False, render <span> chips instead of links. |
prefix |
"#" |
Text prefix shown before each tag name. |
filter_url |
"" |
Build an in-context filter link <filter_url>?<filter_param>=<slug>. |
filter_param |
"tag" |
Query parameter used with filter_url. |
href_pattern |
"" |
Link template with a {slug} placeholder. |
link_class |
"" |
Extra CSS class added to each link. |
channel |
"tag" |
Value for the data-channel attribute (analytics hook). |
placement |
"" |
Value for the data-placement attribute (analytics hook). |
label |
"" |
Accessible aria-label for the chip list. |
Href resolution order: filter_url -> href_pattern -> get_absolute_url()
(when reversible) -> none (renders a <span>).
Style the chips per site via CSS custom properties on the shared classes
(hashtag-chip, hashtag-chip--<variant>); a base stylesheet ships at
hashtag/static/hashtag/hashtag-chips.css.
Filter a list by tag
hashtag.filtering shares the queryset filter and active-tag lookup used by
in-context list views, without referencing any consumer model:
from hashtag.filtering import active_tag_slug, filter_queryset_by_tag
def review_list(request):
slug = active_tag_slug(request) # reads ?tag=<slug>
reviews = filter_queryset_by_tag(Review.objects.all(), slug)
# ...build your own context/template/pagination...
filter_queryset_by_tag accepts a lookup argument (default "tags__slug")
for non-default relation paths; an empty slug returns the queryset unchanged.
Optional canonical tag page (HASHTAG_TAG_URL_NAME)
MyTag.get_absolute_url() is configurable via HASHTAG_TAG_URL_NAME, which
defaults to "tagged" for backward compatibility. Set it to "" to disable
canonical tag pages:
# Enable canonical per-tag URLs resolved with reverse(name, args=[slug]).
HASHTAG_TAG_URL_NAME = "tagged"
# Or disable canonical tag pages entirely (sites that surface tags only as an
# in-context ?tag= filter); get_absolute_url() then raises NoReverseMatch and
# hashtag_chips falls back to filter_url/href_pattern.
HASHTAG_TAG_URL_NAME = ""
Run Example Project
git clone --depth=50 --branch=django-hashtag https://github.com/DLRSP/example.git DLRSP/example
cd DLRSP/example
python manage.py runserver
Now browser the app @ http://127.0.0.1:8000
Metadata
Release files for django-hashtag 0.4.7
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| django_hashtag-0.4.7.tar.gz | 27.8 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| django_hashtag-0.4.7-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 50.1 kB
Release files / django_hashtag-0.4.7.tar.gz
| Download URL | django_hashtag-0.4.7.tar.gz |
|---|---|
| Size | 27.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
eeff965f939ced3f3d661cf90e78ff92e5767e7ed3edf69da52141dd156bbf01
|
|
BLAKE2b-256 checksum How to use checksums |
c71380a57acfe71311c8dd1345dfc721c36a692795da0f36dd1c314b0386479e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Release files / django_hashtag-0.4.7-py3-none-any.whl
| Download URL | django_hashtag-0.4.7-py3-none-any.whl |
|---|---|
| Size | 22.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
083374350ea6ef7f43237e3291d0dfc7cacd33c055327cc84a508870ed019ace
|
|
BLAKE2b-256 checksum How to use checksums |
b5699bff109c76b472aee6a2f8928330d59302ac56dbe2ce5ea41b356bd2d189
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|