{"id":35000251,"url":"https://github.com/hapytex/django-adminlink","last_synced_at":"2025-12-27T03:32:54.158Z","repository":{"id":286339559,"uuid":"961118915","full_name":"hapytex/django-adminlink","owner":"hapytex","description":"Automatically link to the admin detail view if the item is a ForeignKey to a model with an admin.","archived":false,"fork":false,"pushed_at":"2025-07-18T16:36:14.000Z","size":53,"stargazers_count":3,"open_issues_count":1,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-09-27T17:00:48.683Z","etag":null,"topics":["admin","django","modeladmin"],"latest_commit_sha":null,"homepage":"https://pypi.org/project/django-adminlink/","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/hapytex.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null},"funding":{"custom":"https://www.buymeacoffee.com/hapytex"}},"created_at":"2025-04-05T19:45:26.000Z","updated_at":"2025-08-16T07:01:46.000Z","dependencies_parsed_at":null,"dependency_job_id":"386f0f10-0bfe-4bf1-967d-b03d37eb7ee7","html_url":"https://github.com/hapytex/django-adminlink","commit_stats":null,"previous_names":["hapytex/django-adminlink"],"tags_count":4,"template":false,"template_full_name":null,"purl":"pkg:github/hapytex/django-adminlink","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hapytex%2Fdjango-adminlink","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hapytex%2Fdjango-adminlink/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hapytex%2Fdjango-adminlink/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hapytex%2Fdjango-adminlink/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/hapytex","download_url":"https://codeload.github.com/hapytex/django-adminlink/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hapytex%2Fdjango-adminlink/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28071342,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-12-27T02:00:05.897Z","response_time":58,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["admin","django","modeladmin"],"created_at":"2025-12-27T03:32:53.421Z","updated_at":"2025-12-27T03:32:54.147Z","avatar_url":"https://github.com/hapytex.png","language":"Python","funding_links":["https://www.buymeacoffee.com/hapytex"],"categories":[],"sub_categories":[],"readme":"# Django-adminlink\n\n[![PyPi version](https://badgen.net/pypi/v/django-adminlink/)](https://pypi.python.org/pypi/django-adminlink/)\n[![Documentation Status](https://readthedocs.org/projects/django-adminlink/badge/?version=latest)](http://django-adminlink.readthedocs.io/?badge=latest)\n[![PyPi license](https://badgen.net/pypi/license/django-adminlink/)](https://pypi.python.org/pypi/django-adminlink/)\n[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)\n\nThe Django admin allows to list rows in an easy way. Some feature that seems to be \"missing\" is to jump in an efficient way to the detail view of a *related* object. For example if a model `A` has a `ForeignKey` to `B`, then the `ModelAdmin` of `A` can show the `__str__` of `B`, but without a link.\n\nDjango's admin actions are also very useful, but what seems to be missing is an easy way to just run the action on a single row without too much \"hassle\".\n\nThis package provides a mixin to effectively add such links.\n\n## Installation\n\nYou can install the package with:\n\n```\npip install django-adminlink\n```\n\nYou do *not* need to add `'django_adminlink'` to the `INSTALLED_APPS` settings *unless* you use the `SingleItemActionMixin` or a derived product from it. In that case,\nyou need to make use of the `static/js/single_admin_action.js` file that ships with it. Then the `INSTALLED_APPS` looks like:\n\n\n```python3\n# settings.py\n\n# …\n\nINSTALLED_APPS = [\n    # …,\n    'django_adminlink'\n]\n```\n\n## Usage\n\nOnce the package is installed, we can work with the mixins provided by the package.\n\n### Adding links to `ForeignKey` fields\n\nyou can use the `LinkFieldAdminMixin` mixin in the admins where you want `ForeignKey`s and `OneToOneField`s to be linked to the corresponding admin detail view of that object:\n\n```python3\nfrom django.contrib import admin\nfrom django_adminlink.admin import LinkFieldAdminMixin\n\n\n@admin.register(Movie)\nclass MovieAdmin(LinkFieldAdminMixin, admin.ModelAdmin):\n    list_display = ['__str__', 'genre']\n```\n\nIf `genre` is a `ForeignKey` to a `Genre` model for example, and `Genre` has its own `ModelAdmin`, it will automatically convert `genre` into a column that adds a link to the admin detail view of the corresponding genre.\n\n### Single row actions\n\nThe package also provides a `SingleItemActionMixin`, this enables to add a column at the right end of the admin that contains (one or more) buttons. These buttons then run a Django admin action on a *single* record.\n\nOne can specify which actions to run by listing these, for example:\n\n```python3\nfrom django.contrib import admin\nfrom django_adminlink.admin import SingleItemActionMixin\n\n@admin.register(Movie)\nclass MovieAdmin(SingleItemActionMixin, admin.ModelAdmin):\n    action_buttons = {'delete': 'delete_selected'}\n```\n\nOne can work with a dictionary that has as key the \"label\" of the button, and as value the name (key) of the action to work with. This will add a button with the label \"delete\" as last column. When clicked, that row, and only that row is then removed.\n\nThe package does not perform the action itself: it works with a small amount of *JavaScript* that just disables all checkboxes, enables only the checkbox of the selected row, and finally submits the action form, letting Django handle the rest of the logic.\n\nIf the label(s) and action(s) are the same, one can also work with a list of the names of the actions, like:\n\n```python3\nfrom django.contrib import admin\nfrom django_adminlink.admin import SingleItemActionMixin\n\n@admin.register(Movie)\nclass MovieAdmin(SingleItemActionMixin, admin.ModelAdmin):\n    action_buttons = ['delete_selected']\n```\n\n## Grouping actions\n\nThe list of actions is \"flat\". We can add item groups, just like in other Django `ChoiceField`s. For this, we introduced the `GroupedActionAdminMixin`.\n\nThis mixin looks at the actions. We also defined a `@grouped_action` decorator, which does approximately the same as the `@admin.action` decorator, except with an extra parameter `action_group=…`.\n\nWe can register actions like:\n\n```python3\nfrom django.contrib import admin\nfrom django_adminlink.admin import GroupedActionAdminMixin, grouped_action\n\n@admin.register(Movie)\nclass MovieAdmin(GroupedActionAdminMixin, admin.ModelAdmin):\n    action_buttons = ['star', 'unstar', 'clear_comments']\n    \n    @grouped_action(description='star item', action_group='stars')\n    def star(self, request, queryset):\n      # …\n    \n    @grouped_action(description='unstar item', action_group='stars')\n    def unstar(self, request, queryset):\n      # …\n    \n    @grouped_action(description='clear comments', action_group='comments')\n    def clear_comments(self, request, queryset):\n      # …\n```\n\nThe order of the groups is determined by the order of the individual actions: the first action for that group for each group determines how the groups are listed.","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhapytex%2Fdjango-adminlink","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhapytex%2Fdjango-adminlink","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhapytex%2Fdjango-adminlink/lists"}