Skip to content

Getting started with django-generic-links

Python Compatibility Django Compatibility PyPi Version CI badge codecov License

Simple and generic application for Django projects to attach and handle links for any object. Compatible with Django 4.2 to 5.2 and Python 3.10 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 . 

Quick Start

Add generic_links to your INSTALLED_APPS in settings.py:

INSTALLED_APPS = (  # ...  "generic_links",  # ... ) 

Then run the migrations:

python manage.py migrate 

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

>>> 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>]> 

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] 

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> 

Running Tests

Prerequisites: Install Hatch if not already installed: pip install hatch

List available test environments:

hatch env show test 

Run all tests (all Python + Django combinations):

hatch run test:test 

Run tests for specific Python/Django version:

hatch run test.py3.14-5.2:test # Python 3.14 + Django 5.2 hatch run test.py3.13-5.1:test # Python 3.13 + Django 5.1 

Run specific test file:

hatch run test.py3.13-5.2:test tests.test_models 

Coverage:

hatch run test:cov # Run tests with coverage report 

Troubleshooting: If you encounter environment issues, clean and rebuild: hatch env prune