В Django Admin добавление модели в качестве вкладки
Я пытаюсь разобраться с администратором сайта для моего приложения django. У меня есть таблица lorcana_sets
и таблица lorcana_sets_cards
. У lorcana_sets_cards
есть внешний ключ к lorcana_sets
через поле set_id
.
Если я добавлю следующее:
# Lorcana Sets - Cards
class LorcanaSetsCards(admin.ModelAdmin):
list_display = ['name']
list_display_links = ['name']
admin.site.register(lorcana_sets_cards, LorcanaSetsCards)
Я получаю таблицу, в которой перечислены все карты, и могу нажать на название карты в списке и перейти к объекту карты, где я могу редактировать поля этого объекта карты.
Теперь я создал следующее, где у меня есть таблица наборов, и когда я нажимаю на объект набора, появляется вкладка Lorcana Cards, содержащая таблицу, в которой перечислены все карты в этом наборе.
class LorcanaSetsCardsInline(admin.TabularInline):
model = lorcana_sets_cards
extra = 0
fields = ['id', 'number', 'full_name', 'hidden', 'manual']
readonly_fields = ['id', 'number', 'full_name']
@admin.display(description='Name')
def full_name(self, obj):
return f"{obj.name} - {obj.subtitle}" if obj.subtitle else obj.name
def get_queryset(self, request):
qs = super().get_queryset(request)
qs = qs.annotate(number_as_int=Cast('number', output_field=IntegerField())).order_by('number_as_int')
return qs
# Lorcana Sets
class LorcanaSets(admin.ModelAdmin):
list_display = ['code', 'name', 'type', 'release_date']
list_display_links = ['name']
search_fields = ['code', 'name', 'type']
ordering = ['-release_date']
inlines = [LorcanaSetsCardsInline,]
admin.site.register(lorcana_sets, LorcanaSets)
Я хотел бы, чтобы в этой таблице была ссылка, подобная class LorcanaSetsCards(admin.ModelAdmin):
, по которой я мог бы щелкнуть и перейти к объектам этой карты для редактирования любых нужных мне полей.
Я не уверен, возможно ли это или нет. В настоящее время я использую Django==4.2.11
.
Итак, мне удалось разобраться с этим. У меня есть модель администратора набора Lorcana:
# Lorcana Sets
class LorcanaSets(admin.ModelAdmin):
list_display = ['code', 'name', 'type', 'release_date']
list_display_links = ['name']
search_fields = ['code', 'name', 'type']
ordering = ['-release_date']
inlines = [LorcanaSetsCardsInline,]
admin.site.register(lorcana_sets, LorcanaSets)
Я создал модель администратора Lorcana Card, однако я удалил ее из боковой панели навигации, поэтому пользователю приходится переходить к набору, а затем к вкладке Lorcana Card. Я также изменил функциональность "сохранения", чтобы вернуть пользователя на вкладку Lorcana Card на объекте Lorcana Set при нажатии:
# Lorcana Sets - Cards
class LorcanaSetsCardsAdmin(admin.ModelAdmin):
# This removes it from the side navigation bar
def has_module_permission(self, request):
return False
# This changes the "save" functionality to go to the Lorcana Sets object the user was previously on.
def response_change(self, request, obj):
if "_continue" not in request.POST and "_addanother" not in request.POST and "_saveasnew" not in request.POST:
set_id = getattr(obj, 'set_id', None)
return HttpResponseRedirect(f'../../../lorcana_sets/{set_id}/change/#lorcana-cards-tab')
else:
return super().response_change(request, obj)
admin.site.register(lorcana_sets_cards, LorcanaSetsCardsAdmin)
и встроенная модель администрирования Lorcana Cards Admin Model. Это необходимо для отображения списка карточек Lorcana на объекте Lorcana Set:
class LorcanaSetsCardsInlineAdmin(admin.TabularInline):
model = lorcana_sets_cards
extra = 0
fields = ['number', 'full_name_link', 'manual', 'hidden']
readonly_fields = ['number', 'full_name_link']
# Changed the cell to be a link to the Lorcana Card object
@admin.display(description='Name')
def full_name_link(self, obj):
if obj.pk is not None and obj.pk != '':
url = reverse('admin:%s_%s_change' % (obj._meta.app_label, obj._meta.model_name), args=[obj.pk])
return format_html('<a href="{}">{}</a>', url, self.full_name(obj))
else:
return self.full_name(obj)
def full_name(self, obj):
return f"{obj.name} - {obj.subtitle}" if obj.subtitle else obj.name
def get_queryset(self, request):
qs = super().get_queryset(request)
qs = qs.annotate(number_as_int=Cast('number', output_field=IntegerField())).order_by('number_as_int')
return qs
full_name_link.allow_tags = True