Skip to content

Instantly share code, notes, and snippets.

@jamesbrobb
Created October 4, 2023 15:18
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jamesbrobb/255d3d0465147b45cd6f46d6eb36fdd5 to your computer and use it in GitHub Desktop.
Save jamesbrobb/255d3d0465147b45cd6f46d6eb36fdd5 to your computer and use it in GitHub Desktop.
Update of the linkify function for django admin that also handles ManyToManyField
from typing import Optional
from django.contrib import admin
from django.contrib.contenttypes.models import ContentType
from django.db.models import ManyToManyField, ForeignKey, Model
from django.urls import reverse
from django.utils.html import format_html
def create_link(linked_obj, app_label: str, label_prop: Optional[str] = None) -> str:
linked_content_type = ContentType.objects.get_for_model(linked_obj)
model_name = linked_content_type.model
view_name = f"admin:{app_label}_{model_name}_change"
link_url = reverse(view_name, args=[linked_obj.pk])
return "<a href='%s'>%s</a>" % (link_url, getattr(linked_obj, label_prop) if label_prop else linked_obj)
def linkify(field_name: str, label_prop: Optional[str] = None, short_description: Optional[str] = None, as_html_list: bool = False):
def _linkify(obj: Model):
content_type = ContentType.objects.get_for_model(obj)
app_label = content_type.app_label
field_type = obj._meta.get_field(field_name)
items = None
if isinstance(field_type, ManyToManyField):
items = list(getattr(obj, field_name).all())
elif isinstance(field_type, ForeignKey):
items = [getattr(obj, field_name)]
else:
print(f'field_name {field_name} is not ManyToManyField or ForeignKey')
links = [create_link(itm, app_label, label_prop) for itm in items if itm is not None]
if len(links) > 1:
if as_html_list:
html = "<ul>"
for link in links:
html += f'<li>{link}</li>'
html += "</ul>"
else:
html = ", ".join(links)
else:
html = links[0]
return format_html(html)
_linkify.short_description = [short_description, field_name.replace("_", " ").capitalize()][short_description is None]
return _linkify
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment