Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django admin display filter depending on other filters

Here is an example of models:

class Books(models.Model):
    ...

class Chapter(models.Model):
    ... 
    book = models.ForeignKey('Books')

class Exercise(models.Model):
    ...
    book = models.ForeignKey('Books')
    chapter = models.ForeignKey('Chapter') 

And here is the Admin class for exercise:

class ExerciseAdmin(admin.ModelAdmin):
   ...
   list_filter = (('book',admin.RelatedOnlyFieldListFilter),('chapter',admin.RelatedOnlyFieldListFilter))

admin.site.register(Exercise, ExerciseAdmin)

I now have the filters book and chapter for exercise. When I click on a book in the filter book, it shows me all the exercises of the selected book accordingly. But in the list of filter chapter, it still shows all the chapters of all the books.

Is there a way to only display, in the filter chapter, the chapters of the book that I selected in the first filter book? How?

like image 901
Samuel Avatar asked Nov 07 '17 17:11

Samuel


1 Answers

I'm not sure if it's the best way to do it, but here I use the GET parameter of the url from the admin panel to get the ID of the book then I can select the corresponding chapters. And it works!

class ChapterFilter(admin.SimpleListFilter):
    title = 'chapter' 
    parameter_name = 'chapter'
    def lookups(self, request, model_admin):
        if 'book__id__exact' in request.GET:
            id = request.GET['book__id__exact']
            chapters = set([c.chapter for c in model_admin.model.objects.all().filter(book=id)])
        else:
            chapters = set([c.chapter for c in model_admin.model.objects.all()])
        return [(b.id, b.titre) for b in chapters]

    def queryset(self, request, queryset):
        if self.value():
            return queryset.filter(chapter__id__exact=self.value())

class ExerciseAdmin(admin.ModelAdmin):
   list_filter = (('book',admin.RelatedOnlyFieldListFilter), (ChapterFilter))
like image 101
Samuel Avatar answered Sep 30 '22 18:09

Samuel