Stryker
Stryker

Reputation: 6120

How to show child records for only related parent in django Admin?

Model "Playbook" has related child objects "Activities" Need to list_display "Activities" in django admin for each "playbook" object. Currently list_display shows all activity objects for all playbook objects (parent object).

django v 1.10.x, python 3.5.x

Model.py

class PlayBook(TimeStampModel):
    name = models.CharField(max_length=200, unique=True)
    description = models.TextField(blank=True, help_text="Business purpose of the application")
    owner = models.ForeignKey(User, on_delete=models.CASCADE)

    class Meta:
        ordering = ('name',)

    @property
    def short_description(self):
        return truncatechars(self.description, 35)

    def __str__(self):
        return "{}".format(self.name)

class Activity(TimeStampModel):

    minor = 'MINOR'
    normal = 'NORMAL'
    important = 'IMPORTANT'
    critical = 'CRITICAL'

    SEVERITY = (
        (minor, 'Minor'),
        (normal, 'Normal'),
        (important, 'Important'),
        (critical, 'Critical'),
    )

    low = 'LOW'
    high = 'HIGH'
    PRIORITY = (
            (low, 'Low'),
            (normal, 'Normal'),
            (high, 'High'),
            )

    new = 'New'
    in_progress = 'In_Progress'
    needs_info = 'Needs_Info'
    postponed = 'Postponed'
    closed = 'Closed'
    STATUS= (
            (new, 'New'),
            (in_progress, 'In_Progress'),
            (needs_info, 'Needs_Info'),
            (postponed, 'Postponed'),
            (closed, 'Closed'),

            )

    playbook = models.ForeignKey(PlayBook)
    subject = models.CharField(max_length=200, unique=True)
    description = models.TextField(blank=True, help_text="Business purpose of the application")
    manager = models.ForeignKey(User, on_delete=models.CASCADE)
    severity = models.CharField(max_length = 100, choices=SEVERITY, default=normal)
    priority = models.CharField(max_length = 100, choices=PRIORITY, default=normal)
    status = models.CharField(max_length = 100, choices=STATUS, default=new)

    def __str__(self):
        return "{}".format(self.subject)

    class Meta:
        ordering = ('severity',)
    @property
    def short_description(self):
        return truncatechars(self.description, 35)

class ReviewActivity(Activity):
    class Meta:
        proxy=True

    def __str__(self):
        return self.subject.upper()

Admin.py

class ActivityAdmin(admin.TabularInline):
    list_display =['severity','priority', 'subject', 'status_colored','created','updated', 'short_description']

    def status_colored(self, obj):
        colors = {
            'Closed': '#DCE775',
            'Needs_Info': '#F8BBD0'  ,
            'In_Progress': '#FFCCBC',
            'New':'#81D4FA',
            'Postponed': '#CFD8DC'
        }
        return format_html(
            '<b style="background:{};">{}</b>',
            colors[obj.status],
            obj.status,
        )

class ActivityInline(admin.TabularInline):
    model = Activity
    extra = 1

class PlayBookAdmin(admin.ModelAdmin):

    inlines = [
            ActivityInline,
            ]

    list_display =['name','short_description','created', 'updated','owner',]


class ReviewActivityAdmin(admin.ModelAdmin):

    list_display =['severity','priority', 'subject', 'status_colored','created','updated', 'short_description']

    def status_colored(self, obj):
        colors = {
            'Closed': '#DCE775',
            'Needs_Info': '#F8BBD0'  ,
            'In_Progress': '#FFCCBC',
            'New':'#81D4FA',
            'Postponed': '#CFD8DC'
        }
        return format_html(
            '<b style="background:{};">{}</b>',
            colors[obj.status],
            obj.status,
        )

#admin.site.register(Activity, ActivityAdmin)
admin.site.register(PlayBook, PlayBookAdmin)
admin.site.register(ReviewActivity, ReviewActivityAdmin)

Result:

I tried to use the proxy model. But it still displays all child records for all parents. enter image description here

Playbook link displays the following: enter image description here playbook1 shows the tabular display enter image description here

Problem:

Review Activity link displays all activity objects for all playbooks. Need to show activity object for a related playbook.not all playbooks*. See(figure 4): enter image description here

Link to github:

Link to source TaskMaster

Upvotes: 2

Views: 2844

Answers (1)

I just run into a similar situation this morning and this is how i solved it. I am going to use your example to explain.

I defined a new method called activities() in the PlayBook model like so:

class PlayBook(TimeStampModel):
    name = models.CharField(max_length=200, unique=True)
    owner = models.ForeignKey(User, on_delete=models.CASCADE)

    def activities(self):
    qs = self.activity_set.all() # this gets all the child related objects
    for x in qs:
        result = x.subject # here i am just getting one of the fields from the Activities model
    return result

so now in your admin.py you can set your list_diplay as follows

class PlayBookAdmin(admin.ModelAdmin):

    list_display =['activities',] # This will call the activities() method that your created in the models.py and display the result. 

Upvotes: 1

Related Questions