Skip to content

Latest commit

 

History

History
182 lines (127 loc) · 5.43 KB

README.md

File metadata and controls

182 lines (127 loc) · 5.43 KB

django-generic-links

Python Compatibility PyPi Version CI badge codecov License

Simple app to attach links to any Django model. Compatible with Django 4.x to 5.1 and Python 3.9 to 3.13.

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 %}

<hl>{{ artist.name }}</hl>
<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>

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.13-5.1:test will run them for python 3.13 and Django 5.1. Please see possible combinations using hatch env show` ("test" matrix).

License

django-generic-links is released under an BSD License - see the LICENSE file for more information.

Acknowledgements

Develop & built using Hatch project linting - Ruff code style - black

Tools used in building this package:

Posts I learned from: