ron_g
ron_g

Reputation: 1673

Django 1.11 how to resolve list_filter duplicates

In my Model, a __str__(self) that derives the quarter and year from the DateTimeField of when Response was created.

Models.py

class Response(models.Model):

    created = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        msg = u"Q%d %d" %(((self.created.month-1)//3)+1, self.created.year)
        return msg

In Admin, I want to be able to filter records based on the Quarter in which they were submitted (actually, I want to filter by who hasn't submitted a Response for a particular quarter, which I think I can achieve with a well placed tilde later), so I have the following:

Admin.py

class UserAdmin(admin.ModelAdmin):

    list_display = ('username', 'latest_response')
    list_filter = ('response__created', 'response')

    def latest_response(self, obj):
        return obj.response_set.latest('created')

I have submitted four responses so far in testing (through the def __str__ I have 2 x "Q1 2018", and 2 x " - "), and the result looks like this:

UserAdmin table and list_filter result

Any ideas why I am getting 3 x "Q1 2018" and 1 x " - "? I want Only 1 x "Q1 2018" in the filter list

Bonus question - any idea how to set a limit to the number of items listed in the filter_list (by response)? I want to limit them to the latest 4 which, might be problematic as I'm using a string.

EDIT

Just noticed in the console log that the filters are using a GET request based on the Response ID:

"GET /admin/auth/user/?response__id__exact=1 HTTP/1.1" 200 14277
"GET /admin/jsi18n/ HTTP/1.1" 200 3217
"GET /admin/auth/user/?response__id__exact=2 HTTP/1.1" 200 14277
"GET /admin/jsi18n/ HTTP/1.1" 200 3217
"GET /admin/auth/user/?response__id__exact=3 HTTP/1.1" 200 14270
"GET /admin/jsi18n/ HTTP/1.1" 200 3217
"GET /admin/auth/user/?response__isnull=True HTTP/1.1" 200 14599
"GET /admin/jsi18n/ HTTP/1.1" 200 3217

So, as I understand it, the by response filter is displaying the common name (Q1 2018) for four object's (distinguished by their ID).

How do I go about filtering the objects based on their common name/self? I guess via another def to the Response class?

Upvotes: 0

Views: 144

Answers (1)

Walucas
Walucas

Reputation: 2568

Usually I reserve the def __str__(self): as an identification for my class. Create a

def Quarter(self): 
    msg = u"Q%d %d" %(((self.created.month-1)//3)+1, self.created.year)
    return msg

And then use that to filter:

list_filter = ('response__created', 'Quarter')

Upvotes: 1

Related Questions