A good way to filter "published"

57 views
Skip to first unread message

Tzu-ping Chung

unread,
Jun 18, 2013, 3:50:23 AM6/18/13
to mezzani...@googlegroups.com
Hi,

I've been trying to use PublishedManager's `published` method to build custom queries for some custom logic. What's bothering me is that `published` only works with PublishedManager, so I can only do SomeDisaplayable.objects.published(user).blahblahblah. This makes it more difficult to reuse QuerySet objects, especially if I want to apply `published` to a ForeignKey reverse (for example, filtering user.blogposts).

My current solution is to use __in like this

published = BlogPosts.published(user)
viewable_posts = some_author.blogposts.filter(id__in=published.values_list('id', flat=True))

which is obviously not very scalable. What I can think of is to extract the Q object from `published` into another method (property?) like this
 
class PublishedManager(Manager):
    def published(self, for_user=None):
        return self.filter(self.get_published_query(for_user))

    def get_published_query(self, for_user=None):
        if for_user is not None and for_user.is_staff:
            return Q(pk__isnull=False)   # Another way of saying all()
        return (
            Q(publish_date__lte=now()) | Q(publish_date__isnull=True),
            Q(expiry_date__gte=now()) | Q(expiry_date__isnull=True),
            Q(status=CONTENT_STATUS_PUBLISHED))
         ) 

So that in the above scenario we can have

viewable_posts = some_author.blogposts.filter(BlogPosts.objects.get_published_query(user))

which don't have a scalability problem.

What I wish to know is, am I missing a better way of doing this? I was planning to send a pull request, but figure that should ask about it first.

p.s. `get_published_query` is probably not a good name, but I am out of ideas right now. Any suggestion is welcome. The pk__isnull thing seems dumb too.

Stephen McDonald

unread,
Jun 18, 2013, 4:52:57 PM6/18/13
to mezzani...@googlegroups.com
This might be what you're looking for:


--
You received this message because you are subscribed to the Google Groups "Mezzanine Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to mezzanine-use...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
 
 



--
Stephen McDonald
http://jupo.org

Tzu-ping Chung

unread,
Jun 18, 2013, 9:57:22 PM6/18/13
to mezzani...@googlegroups.com, st...@jupo.org
Hi Steve,

Well yes, this works in the particular use case, but what I was trying to say is that we lack a good way to reuse the published logic. Even if you use PassThroughManager you would still need to duplicate the code in PublishedManager unless you do some funky hacks like this

class PublishedPassThroughManager(PassThroughManager):
    published = PublishedManager.published

unless there are some techniques that I'm not aware of. It also takes some monkey-patching to apply this approach cleanly on Mezzanine and Cartridge's built-in classes (Page, Product, etc.) That's why I proposed extracting the Q object from the filtering method itself -- To avoid duplicating logic.


Stephen McDonald於 2013年6月19日星期三UTC+8上午4時52分57秒寫道:
Reply all
Reply to author
Forward
0 new messages