django-generic-links
Simple app to attach links to any Django model. Compatible with Django 4.2 to 6.1 and Python 3.12 to 3.14.
Features
- Model for creating generic link relations
- Reverse Generic Relation (Django) for your models
- Model Admin
- Generic inline admin to manage any model's generic links
- A template tag to get all links for a given model instance
- A fully working example project
Installation
Via pip command:
pip install django-generic-links
...or you can clone the repo and install it using pip too:
git clone git://github.com/matagus/django-generic-links.git
cd django-generic-links
pip install -e .
then add generic_links to your settings.py:
INSTALLED_APPS = (
# ...
"generic_links",
)
then run the migrations:
python manage.py migrate
and finally add the reverse generic relation to each of the models you're going to add generic links to:
from django.db import models
from django.contrib.contenttypes.fields import GenericRelation
class Artist(models.Model):
name = models.CharField(max_length=100)
bio = models.TextField()
# This is important so that we can get the GenericLink related instances for an object of this model
generic_links = GenericRelation("generic_links.GenericLink")
class Album(models.Model):
title = models.CharField(max_length=100)
artist = models.ForeignKey(Artist, on_delete=models.CASCADE)
release_date = models.DateField(null=True, blank=True)
generic_links = GenericRelation("generic_links.GenericLink")
Usage
Using django-generic-links models
>>> from generic_links.models import GenericLink
>>> from music.models import Artist
>>>
>>> # Get an artist from the database...
>>> lou_reed = Artist.objects.get(pk=1)
>>> lou_reed
<Artist: Lou Reed>
>>>
>>> # Create the first link
>>> link1 = GenericLink(title="Wikipedia Page", url="http://en.wikipedia.org/wiki/Lou_Reed", content_object=lou_reed)
>>> link1.save()
>>>
>>> # and then a second one
>>> link2 = GenericLink(title="Encyclopaedia Britannica", url="https://www.britannica.com/biography/Lou-Reed",
content_object=lou_reed)
>>> link2.save()
>>>
>>> # Now get all the links for the artist object:
>>> lou_reed.generic_links.all()
<QuerySet [<GenericLink: Encyclopaedia Britannica :: https://www.britannica.com/biography/Lou-Reed>,
<GenericLink: Wikipedia Page :: https://en.wikipedia.org/wiki/Lou_Reed>]>
Generic Links Inline Admin
Since a GenericLink instance will be associated to another object you usually
wish to show an inline model admin form in that model form.
from django.contrib import admin
from generic_links.admin import GenericLinkStackedInline
from music_app.models import Artist
@admin.register(Artist)
class ArtistAdmin(admin.ModelAdmin):
# ...
inlines = [GenericLinkStackedInline]
Using django-generic-links templatetags
Now imagine you have an artist page. You're passing artist object using template
context and you want to get all the links for it:
{% load generic_links_tags %}
<h1>{{ artist.name }}</h1>
<p>{{ artist.description }}</p>
<h2>Links for {{ artist.name }}</h2>
{% get_links_for artist as artist_links %}
<ul>
{% for link in artist_links %}
<li><a href="{{ link.url }}" title="{{ link.title }}">{{ link.title }}</a></li>
{% endfor %}
</ul>
All of the above is wired up in a runnable form under example_project/: artist and album pages that use
this tag, plus the inline admin. See Contributing.md to start it.
Contributing
Contributions are welcome! ❤️
Please read Contributing.md for detailed instructions on how to help.
Running Tests
hatch run test:test will run the tests in every Python + Django versions combination.
hatch run test.py3.14-5.2:test will run them for python 3.14 and Django 5.2. Please see possible combinations using
hatch env show ("test" matrix).
License
django-generic-links is released under a BSD License - see the LICENSE file
for more information.
Acknowledgements
Tools used in building this package:
- Cookiecutter and cookiecutter-djangopackage for rendering this package.
Posts I learned from:
Metadata
Release files for django-generic-links 0.15.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| django_generic_links-0.15.0.tar.gz | 7.6 kB | Without provenance | Details for django_generic_links-0.15.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| django_generic_links-0.15.0-py3-none-any.whl | Python 3 | none | any | Details for django_generic_links-0.15.0-py3-none-any.whl |
Total release size: 18.6 kB
Release files / django_generic_links-0.15.0.tar.gz
| Download URL | django_generic_links-0.15.0.tar.gz |
|---|---|
| Size | 7.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
4c96fbf7c3dcb781b7dd99cddd411bb6947080ef740e34b1a7d78026b939aa7e
|
|
BLAKE2b-256 checksum How to use checksums |
b263f4b984927dac3e3ba67a838e7c18f89de66544068b1895e717897915e0fc
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Release files / django_generic_links-0.15.0-py3-none-any.whl
| Download URL | django_generic_links-0.15.0-py3-none-any.whl |
|---|---|
| Size | 11.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
3c4375bbc973917b3970702a5292fcac87d732d1859c924255f150dd8b5f967d
|
|
BLAKE2b-256 checksum How to use checksums |
8d0fd05906465a238e84876b46be0f3f852321488e289490528e8fc9b4929456
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Security for django-generic-links 0.15.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.