LoginSignup
2
1

More than 5 years have passed since last update.

[Django]管理画面の一覧表示部分に別テーブルのフィールドを表示する

Last updated at Posted at 2019-04-05

はじめに

「[Django]管理画面の一覧表示部分に、(表示対象のテーブルで外部キーなどでの関連もさせていない)別テーブルのフィールドを表示する」

最終的に結構単純でしたが、同じようなことをしている人が少なくて割と悩んだのでメモ。
多分ドキュメントに丁寧に目を通した人にとっては当たり前のことかも。

やりたいこと

上の画面を下のような表示にしたかったのですが、この時、DBの構成は下記のER図のようになっており、日時系の値とそれ以外の値は別DBのフィールドのため、単純にlist_displayで追加することができなかった。

[やりたい画面レイアウト]
図1.png

[ER図]
(記事用に適当に書き換えたので、ER図と下の方のコードの整合性保ってない部分もあるかも)
スクリーンショット 2019-04-05 14.14.53.png

要点

特に重要なのは下記の部分ですが、一応全貌を載せておきます。

重要部分1
    def plan_start_datetime(self, obj):
        list_got_objects = list(Datetime.objects.all().values_list('plan_start_datetime', flat=True))

        return list_got_objects

※1:取得したい情報の条件(例:「id=1」など)

重要部分2
    list_display = (
                    'plan_start_datetime',
                   )
要点1.

<テーブル名>.objects.all() の戻り値はQuerySetなので、values_list() で値を取得する必要がある。

要点2.

values_list() で取得した値をスライスして取得した「文字列」をlist_display に渡す。

以下、全貌

models.py
# coding: utf-8
from django.db import models
from django.utils import timezone
from django.core.validators import MaxValueValidator


# コードがforeign keyとして使用されるため、このクラスを先に定義している
class M_branch(models.Model):

    def __str__(self):
        return self.name

    code = models.CharField(max_length=4, primary_key=True)
    name = models.CharField(max_length=128)

# コードがforeign keyとして使用されるため、このクラスを先に定義している
class M_workplace(models.Model):

    def __str__(self):
        return self.name

    branch_code = models.ForeignKey(M_branch, on_delete=models.CASCADE)
    code = models.CharField(max_length=4)
    name = models.CharField(max_length=128)


class Report(models.Model):

    def __str__(self):
        return self.application_id

    application_id = models.CharField(max_length=32, primary_key=True)
    branch_code = models.ForeignKey(M_branch, on_delete=models.DO_NOTHING)
    workplace_code = models.ForeignKey(M_workplace, on_delete=models.DO_NOTHING)


class Datetime(models.Model):

    def __str__(self):
        return self.plan_start_datetime

    application_id = models.OneToOneField(Report, on_delete=models.CASCADE)
    plan_start_datetime = models.DateTimeField()
    plan_end_datetime = models.DateTimeField()
    actual_start_datetime = models.DateTimeField()
    actual_end_datetime = models.DateTimeField()

admin.py
from django.contrib import admin

from .models import Report, Datetime, Participant, M_branch, M_workplace


# TODO DatetimeやParticipantテーブルから必要な情報を取得して同じ表に表示する
class ReportAdmin(admin.ModelAdmin):
    fieldsets = [
        ('申請ID', {'fields': ['application_id']}),
        ('支部コード', {'fields': ['branch_code']}),
        ('職場コード', {'fields': ['workplace_code']}),
    ]
    list_display = ('application_id',
                    'branch_code',
                    'workplace_code',
                    'plan_start_datetime',
                    'plan_end_datetime',
                    'actual_start_datetime',
                    'actual_end_datetime',
                    )
    def plan_start_datetime(self, obj):
        list_got_objects = list(Datetime.objects.all().values_list('plan_start_datetime', flat=True))
        return plan_start_datetime
    plan_start_datetime.short_description = 'plan_start_datetime'

    def plan_end_datetime(self, obj):
        list_got_objects = list(Datetime.objects.all().values_list('plan_end_datetime', flat=True))
        return plan_end_datetime
    plan_end_datetime.short_description = 'plan_end_datetime'

    def actual_start_datetime(self, obj):
        list_got_objects = list(Datetime.objects.all().values_list('actual_start_datetime', flat=True))
        return actual_start_datetime
    actual_start_datetime.short_description = 'actual_start_datetime'

    def actual_end_datetime(self, obj):
        list_got_objects = list(Datetime.objects.all().values_list('actual_end_datetime', flat=True))
        return actual_end_datetime
    actual_end_datetime.short_description = 'actual_end_datetime'


class M_branchAdmin(admin.ModelAdmin):
    fieldsets = [
        ('支部コード', {'fields': ['code']}),
        ('支部名', {'fields': ['name']}),
    ]
    list_display = ('name', 'code')


class M_workplaceAdmin(admin.ModelAdmin):
    fieldsets = [
        ('支部コード', {'fields': ['branch_code']}),
        ('職場コード', {'fields': ['code']}),
        ('職場名',    {'fields': ['name']}),
    ]
    list_display = ('name', 'code', 'branch_code')

admin.site.register(Report, ReportAdmin)
admin.site.register(M_branch, M_branchAdmin)
admin.site.register(M_workplace, M_workplaceAdmin)

以上。

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1