django-generic-links
====================
![Python Compatibility](https://img.shields.io/badge/python-3.9%20%7C%203.10%20%7C%203.11%20%7C%203.12%20%7C%203.13-blue.svg) [![PyPi Version](https://img.shields.io/pypi/v/django-generic-links.svg)](https://pypi.python.org/pypi/django-generic-links) ![CI badge](https://github.com/matagus/django-generic-links/actions/workflows/ci.yml/badge.svg) [![codecov](https://codecov.io/gh/matagus/django-generic-links/graph/badge.svg?token=a64SxEDQk0)](https://codecov.io/gh/matagus/django-generic-links) [![License](https://img.shields.io/badge/License-BSD_3--Clause-blue.svg)](https://opensource.org/licenses/BSD-3-Clause)
![Python Compatibility](https://img.shields.io/badge/python-3.9%20%7C%203.10%20%7C%203.11%20%7C%203.12%20%7C%203.12-blue.svg) [![PyPi Version](https://img.shields.io/pypi/v/django-generic-links.svg)](https://pypi.python.org/pypi/django-generic-links) ![CI badge](https://github.com/matagus/django-generic-links/actions/workflows/ci.yml/badge.svg) [![codecov](https://codecov.io/gh/matagus/django-generic-links/graph/badge.svg?token=a64SxEDQk0)](https://codecov.io/gh/matagus/django-generic-links) [![License](https://img.shields.io/badge/License-BSD_3--Clause-blue.svg)](https://opensource.org/licenses/BSD-3-Clause)
Simple app to attach links to any Django model. Compatible with Django 4.x to 5.0 and Python 3.9 to 3.12.
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:
```bash
pip install django-generic-links
```
...or you can clone the repo and install it using `pip` too:
```bash
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`:
```python
INSTALLED_APPS = (
# ...
"generic_links",
)
```
then run the migrations:
```bash
python manage.py migrate
```
and finally add the reverse generic relation to each of the models you're going to add generic links to:
```python
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
---------------------------------
```python
>>> 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.
```python
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:
```html
{% 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](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](https://img.shields.io/badge/%F0%9F%A5%9A-Hatch-4051b5.svg)](https://github.com/pypa/hatch) [![linting - Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff) [![code style - black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)
Tools used in building this package:
- [Cookiecutter](https://github.com/audreyr/cookiecutter) and [cookiecutter-djangopackage](https://github.com/pydanny/cookiecutter-djangopackage) for rendering this package.
Posts I learned from:
- [Switching to Hatch](https://andrich.me/2023/08/switching-to-hatch/)
- [Automate Hatch Publish with GitHub Actions](https://blog.pecar.me/automate-hatch-publish)
Raw data
{
"_id": null,
"home_page": null,
"name": "django-generic-links",
"maintainer": null,
"docs_url": null,
"requires_python": null,
"maintainer_email": null,
"keywords": "django, generic app, generic links, links, urls",
"author": null,
"author_email": "Matias Agustin Mendez <matagus@gmail.com>",
"download_url": "https://files.pythonhosted.org/packages/52/94/05d1dc2334ccabe381a4c884d605531e20df1af5f8d325eddf697db27244/django_generic_links-0.11.0.tar.gz",
"platform": null,
"description": "django-generic-links\n====================\n\n![Python Compatibility](https://img.shields.io/badge/python-3.9%20%7C%203.10%20%7C%203.11%20%7C%203.12%20%7C%203.13-blue.svg) [![PyPi Version](https://img.shields.io/pypi/v/django-generic-links.svg)](https://pypi.python.org/pypi/django-generic-links) ![CI badge](https://github.com/matagus/django-generic-links/actions/workflows/ci.yml/badge.svg) [![codecov](https://codecov.io/gh/matagus/django-generic-links/graph/badge.svg?token=a64SxEDQk0)](https://codecov.io/gh/matagus/django-generic-links) [![License](https://img.shields.io/badge/License-BSD_3--Clause-blue.svg)](https://opensource.org/licenses/BSD-3-Clause)\n![Python Compatibility](https://img.shields.io/badge/python-3.9%20%7C%203.10%20%7C%203.11%20%7C%203.12%20%7C%203.12-blue.svg) [![PyPi Version](https://img.shields.io/pypi/v/django-generic-links.svg)](https://pypi.python.org/pypi/django-generic-links) ![CI badge](https://github.com/matagus/django-generic-links/actions/workflows/ci.yml/badge.svg) [![codecov](https://codecov.io/gh/matagus/django-generic-links/graph/badge.svg?token=a64SxEDQk0)](https://codecov.io/gh/matagus/django-generic-links) [![License](https://img.shields.io/badge/License-BSD_3--Clause-blue.svg)](https://opensource.org/licenses/BSD-3-Clause)\n\nSimple app to attach links to any Django model. Compatible with Django 4.x to 5.0 and Python 3.9 to 3.12.\n\nFeatures\n========\n\n- Model for creating generic link relations\n- Reverse Generic Relation (Django) for your models\n- Model Admin\n- Generic inline admin to manage any model's generic links\n- A template tag to get all links for a given model instance\n- A fully working example project\n\n\nInstallation\n============\n\nVia `pip` command:\n\n```bash\npip install django-generic-links\n```\n\n...or you can clone the repo and install it using `pip` too:\n\n```bash\ngit clone git://github.com/matagus/django-generic-links.git\ncd django-generic-links\npip install -e .\n```\n\nthen add `generic_links` to your `settings.py`:\n\n```python\nINSTALLED_APPS = (\n # ...\n \"generic_links\",\n)\n```\n\nthen run the migrations:\n\n```bash\npython manage.py migrate\n```\n\nand finally add the reverse generic relation to each of the models you're going to add generic links to:\n\n```python\nfrom django.db import models\nfrom django.contrib.contenttypes.fields import GenericRelation\n\n\nclass Artist(models.Model):\n name = models.CharField(max_length=100)\n bio = models.TextField()\n\n # This is important so that we can get the GenericLink related instances for an object of this model\n generic_links = GenericRelation(\"generic_links.GenericLink\")\n\n\nclass Album(models.Model):\n title = models.CharField(max_length=100)\n artist = models.ForeignKey(Artist, on_delete=models.CASCADE)\n release_date = models.DateField(null=True, blank=True)\n\n generic_links = GenericRelation(\"generic_links.GenericLink\")\n```\n\n\nUsage\n=====\n\nUsing django-generic-links models\n---------------------------------\n\n```python\n>>> from generic_links.models import GenericLink\n>>> from music.models import Artist\n>>>\n>>> # Get an artist from the database...\n>>> lou_reed = Artist.objects.get(pk=1)\n>>> lou_reed\n<Artist: Lou Reed>\n>>>\n>>> # Create the first link\n>>> link1 = GenericLink(title=\"Wikipedia Page\", url=\"http://en.wikipedia.org/wiki/Lou_Reed\", content_object=lou_reed)\n>>> link1.save()\n>>>\n>>> # and then a second one\n>>> link2 = GenericLink(title=\"Encyclopaedia Britannica\", url=\"https://www.britannica.com/biography/Lou-Reed\",\ncontent_object=lou_reed)\n>>> link2.save()\n>>>\n>>> # Now get all the links for the artist object:\n>>> lou_reed.generic_links.all()\n<QuerySet [<GenericLink: Encyclopaedia Britannica :: https://www.britannica.com/biography/Lou-Reed>,\n<GenericLink: Wikipedia Page :: https://en.wikipedia.org/wiki/Lou_Reed>]>\n```\n\nGeneric Links Inline Admin\n--------------------------\n\nSince a `GenericLink` instance will be associated to another object you usually\nwish to show an inline model admin form in that model form.\n\n```python\nfrom django.contrib import admin\n\nfrom generic_links.admin import GenericLinkStackedInline\n\nfrom music_app.models import Artist\n\n\n@admin.register(Artist)\nclass ArtistAdmin(admin.ModelAdmin):\n # ...\n inlines = [GenericLinkStackedInline]\n```\n\n\nUsing django-generic-links templatetags\n---------------------------------------\n\nNow imagine you have an artist page. You're passing `artist` object using template\ncontext and you want to get all the links for it:\n\n```html\n{% load generic_links_tags %}\n\n<hl>{{ artist.name }}</hl>\n<p>{{ artist.description }}</p>\n<h2>Links for {{ artist.name }}</h2>\n{% get_links_for artist as artist_links %}\n<ul>\n{% for link in artist_links %}\n \u2039li><a href=\"{{ link.url }}\" title=\"{{ link.title }}\"> {{ link. title }}</a></li>\n{% endfor %}\n</ul>\n```\n\n\nContributing\n============\n\nContributions are welcome! \u2764\ufe0f\n\nPlease read [Contributing.md](CONTRIBUTING.md) for detailed instructions on how to help.\n\nRunning Tests\n-------------\n\n`hatch run test:test` will run the tests in every Python + Django versions combination.\n\n`hatch run test.py3.13-5.1:test will run them for python 3.13 and Django 5.1. Please see possible combinations using\n`hatch env show` (\"test\" matrix).\n\n\nLicense\n=======\n\n`django-generic-links` is released under an BSD License - see the `LICENSE` file\nfor more information.\n\n\nAcknowledgements\n================\n\nDevelop & built using [![Hatch project](https://img.shields.io/badge/%F0%9F%A5%9A-Hatch-4051b5.svg)](https://github.com/pypa/hatch) [![linting - Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff) [![code style - black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)\n\nTools used in building this package:\n\n- [Cookiecutter](https://github.com/audreyr/cookiecutter) and [cookiecutter-djangopackage](https://github.com/pydanny/cookiecutter-djangopackage) for rendering this package.\n\nPosts I learned from:\n\n- [Switching to Hatch](https://andrich.me/2023/08/switching-to-hatch/)\n- [Automate Hatch Publish with GitHub Actions](https://blog.pecar.me/automate-hatch-publish)\n",
"bugtrack_url": null,
"license": null,
"summary": "Simple and generic application for Django projects to attach and handle links for any object",
"version": "0.11.0",
"project_urls": {
"Changelog": "https://githib.com/matagus/django-generic-links/releases",
"Homepage": "https://github.com/matagus/django-generic-links",
"Issues": "https://.github.com/matagus/django-generic-links/issues",
"Pypi": "https://pypi.org/project/django-generic-links",
"Repository": "https://github.com/matagus/django-generic-links"
},
"split_keywords": [
"django",
" generic app",
" generic links",
" links",
" urls"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "438fbd8e5f39fc2e01bd50b3a8792441fe326f1dccfa62523c64e9df2dbac8a9",
"md5": "6ab32f50a806415591fb4d287c469105",
"sha256": "75dbd0f6b062b0feb1d3de95adc63820244ee4ec57293e36876128673626c893"
},
"downloads": -1,
"filename": "django_generic_links-0.11.0-py2.py3-none-any.whl",
"has_sig": false,
"md5_digest": "6ab32f50a806415591fb4d287c469105",
"packagetype": "bdist_wheel",
"python_version": "py2.py3",
"requires_python": null,
"size": 11693,
"upload_time": "2024-11-06T13:53:02",
"upload_time_iso_8601": "2024-11-06T13:53:02.948262Z",
"url": "https://files.pythonhosted.org/packages/43/8f/bd8e5f39fc2e01bd50b3a8792441fe326f1dccfa62523c64e9df2dbac8a9/django_generic_links-0.11.0-py2.py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "529405d1dc2334ccabe381a4c884d605531e20df1af5f8d325eddf697db27244",
"md5": "5d4872ae4aa0cad0e5a83485f89dbd03",
"sha256": "dbc3ae68b5899daf6e6e31369e24f55a543490a18e7e6abf7c5cb9102b3d683a"
},
"downloads": -1,
"filename": "django_generic_links-0.11.0.tar.gz",
"has_sig": false,
"md5_digest": "5d4872ae4aa0cad0e5a83485f89dbd03",
"packagetype": "sdist",
"python_version": "source",
"requires_python": null,
"size": 7319,
"upload_time": "2024-11-06T13:53:04",
"upload_time_iso_8601": "2024-11-06T13:53:04.709041Z",
"url": "https://files.pythonhosted.org/packages/52/94/05d1dc2334ccabe381a4c884d605531e20df1af5f8d325eddf697db27244/django_generic_links-0.11.0.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2024-11-06 13:53:04",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "matagus",
"github_project": "django-generic-links",
"travis_ci": false,
"coveralls": true,
"github_actions": true,
"lcname": "django-generic-links"
}