Django 如何在管理中将外键显示为链接列表?

问题描述 投票:0回答:1

假设我有两个 Django 模型

Room
User
。我将在此处保留通用模型的开放状态。

User
我与
Room
有一对多的关系,这样一个房间可以被许多用户使用,但它的使用是可选的:

room = models.ForeignKey(Room, blank=True, null=True, on_delete=models.SET_NULL, related_name='users')

如何在

Room admin page
显示包含所有用户的部分?

我已经尝试过

admin.TabularInline
,它显示所有用户字段都是可编辑的,但我想要一个用户链接列表(例如用户名),并且可以将现有用户添加到列表中。

我还尝试将

related_name
用户添加到 Room
ModelAdmin
list_display
属性,但没有任何反应 :D

python django django-models django-admin
1个回答
0
投票

老问题,但我认为仍然相关。以下解决方案是根据相关问题中建议的答案编写的。效果很好。

from django.contrib import admin
from django.urls import reverse
from django.utils.html import format_html, format_html_join
from django.utils.safestring import mark_safe

from .models import Room


def queryset_as_ul(qs, with_links=False, empty_value=''):
   """Takes in a queryset and renders it as a list (of links).
   """
   if with_links:
      meta = qs.model._meta
      view_name = f'admin:{meta.app_label}_{meta.model_name}_change'
      items = format_html_join(
         mark_safe('\n'),
         '<li><a href="{}">{}</a></li>',
         ((reverse(view_name, args=[r.pk]), r) for r in qs)
      )
   else:
      items = format_html_join(
         mark_safe('\n'),
         '<li>{}</li>',
         ((r,) for r in qs),
      )

   if items:
      return format_html('<ul>{}</ul>', items)
   else:
      return empty_value


class RoomAdmin(admin.ModelAdmin):
   # Adds the list of users beneath the room form.
   readonly_fields = ['roommates']

   @admin.display('Users')
   def roommates(self, instance):
      # Filter your queryset however you like.
      qs_users = instance.user_set.all()
      return queryset_as_ul(
         qs_users,
         with_links=True,
         empty_value=mark_safe('<span class="errors">None.</span>'),
      )

admin.site.register(Room, RoomAdmin)

(我发现您还需要一些 CSS 来设置列表样式,因为默认情况下它排列得不太好。留给读者作为练习。)

© www.soinside.com 2019 - 2024. All rights reserved.