1

I set up 2 models Article and Taxonomy. Taxonomy is an MPTTModel Subclass.

All is working fine except one thing : If I select a parent node that has no Article linked to it it will not display Articles linked to children nodes.

So I am trying to code my custom filter but I get stuck with queryset filtering. How can I filter this queryset to display all Articles linked to children Nodes IF I click on a parent node ? :

class TaxonomyFilter(SimpleListFilter):
    """
    Return incremented taxonomy list. Filtering by parent node display all children.
    """
    title = ('Index')
    parameter_name = 'node_id'

    def lookups(self, request, model_admin):
        taxos = Taxonomy.objects.all()
        leafs = []
        for taxo in taxos:
            leafs.append((taxo.id,(taxo.name)))

        return leafs


    def queryset(self,request,queryset):
        """
        Filter list by displaying children if parent node has any.
        """
        if self.value():
            return queryset.filter()  
        else:
            return queryset
Karatheodory
  • 895
  • 10
  • 16
Matthieu
  • 1,084
  • 12
  • 23

3 Answers3

2

Not sure if it's ok to answer our own question but for anyone else facing same issue here is the "working but not bullet proof" snippet

    def queryset(self,request,queryset):
    """
    Filter list by displaying children if parent node has any.
    """
    descendants = Taxonomy.objects.get(pk=self.value()).get_descendants(include_self=True)

    descendant_list = []
    for descendant in descendants:
        descendant_list.append(descendant.id)

    return queryset.filter(taxonomy__in=descendant_list)
Matthieu
  • 1,084
  • 12
  • 23
1

Julius: This is a bit lower-level, but does less queries than your solution (2 instead of 3)

def queryset(self, request, queryset):
    """
    Filter list by displaying children if parent node has any.
    """
    t = Taxonomy.objects.get(pk=self.value())

    return queryset.filter(taxonomy__lft__gte=t.lft, taxonomy__rght__lte=t.rght)
Karatheodory
  • 895
  • 10
  • 16
craigds
  • 2,072
  • 14
  • 25
1

With django-mptt there are some cases where the query as described by craigds might not work, as the left and right leaf attributes are not unique in any way. To avoid false matches you can use the tree_id field that comes with django-mptt:

t = Taxonomy.objects.get(pk=self.value())

return queryset.filter(
    taxonomy__tree_id=t.tree_id,
    taxonomy__lft__gte=t.lft,
    taxonomy__rght__lte=t.rght
)
jwa
  • 68
  • 1
  • 4