Search code examples
djangodjango-querysetdjango-mpttmptt

django-mptt : Filter all categories having an online entry


I am passing this Django Blog App category system to django-mptt.

The problem I have is about the _get_online_category method. This method allows me to get only the category having an Entry.

def _get_online_categories(self):
    """
    Returns categories with entries "online" inside.
    Access this through the property ``online_entry_set``.
    """
    from models import Entry
    return Category.objects.filter(entries__status=Entry.STATUS_ONLINE).distinct()

How can I modify it so I will have also categories having categories having an entry ?

For example :

I have Spain > Malaga and Malaga got an Entry with the previous method, I will get only Malaga but not Spain I would like to have both.

Second question :

How to get all entries from a parent category ?

For exemple get Malaga's post from Spain ?

def _get_online_entries(self):
    """
    Returns entries in this category with status of "online".
    Access this through the property ``online_entry_set``.
    """
    from models import Entry        
    return self.entries.filter(status=Entry.STATUS_ONLINE)

online_entries = property(_get_online_entries)

This returns empty result for Spain.


Solution

  • This looks to be a good solution for the first way :

    def _get_online_categories(self):
        """
        Returns categories with entries "online" inside.
        Access this through the property ``online_entry_set``.
        """
        from models import Entry
        queryset =  self.categories.filter(entries__status=Entry.STATUS_ONLINE)
    
        new_queryset = queryset.none() | queryset
        for obj in queryset:
            new_queryset = new_queryset | obj.get_ancestors()
        return new_queryset
    

    Second question

    Something like this will make it :

    def _get_online_entries(self):
        """
        Returns entries in this category with status of "online".
        Access this through the property ``online_entry_set``.
        """
        from models import Entry        
        return Entry.objects.filter(status=Entry.STATUS_ONLINE, 
                                    category__lft__gte=self.lft, 
                                    category__rght__lte=self.rght)
    
    online_entries = property(_get_online_entries)