<s> from __future__ import absolute_import , unicode_literals <EOL> from collections import defaultdict <EOL> from django import VERSION as DJANGO_VERSION <EOL> from django . apps import apps <EOL> from django . contrib . contenttypes . models import ContentType <EOL> from django . db . models import Q <EOL> from treebeard . mp_tree import MP_NodeQuerySet <EOL> from wagtail . wagtailsearch . queryset import SearchableQuerySetMixin <EOL> class TreeQuerySet ( MP_NodeQuerySet ) : <EOL> """<STR_LIT>""" <EOL> def descendant_of_q ( self , other , inclusive = False ) : <EOL> q = Q ( path__startswith = other . path ) & Q ( depth__gte = other . depth ) <EOL> if not inclusive : <EOL> q &= ~ Q ( pk = other . pk ) <EOL> return q <EOL> def descendant_of ( self , other , inclusive = False ) : <EOL> """<STR_LIT>""" <EOL> return self . filter ( self . descendant_of_q ( other , inclusive ) ) <EOL> def not_descendant_of ( self , other , inclusive = False ) : <EOL> """<STR_LIT>""" <EOL> return self . exclude ( self . descendant_of_q ( other , inclusive ) ) <EOL> def child_of_q ( self , other ) : <EOL> return self . descendant_of_q ( other ) & Q ( depth = other . depth + <NUM_LIT:1> ) <EOL> def child_of ( self , other ) : <EOL> """<STR_LIT>""" <EOL> return self . filter ( self . child_of_q ( other ) ) <EOL> def not_child_of ( self , other ) : <EOL> """<STR_LIT>""" <EOL> return self . exclude ( self . child_of_q ( other ) ) <EOL> def ancestor_of_q ( self , other , inclusive = False ) : <EOL> paths = [ <EOL> other . path [ <NUM_LIT:0> : pos ] <EOL> for pos in range ( <NUM_LIT:0> , len ( other . path ) + <NUM_LIT:1> , other . steplen ) [ <NUM_LIT:1> : ] <EOL> ] <EOL> q = Q ( path__in = paths ) <EOL> if not inclusive : <EOL> q &= ~ Q ( pk = other . pk ) <EOL> return q <EOL> def ancestor_of ( self , other , inclusive = False ) : <EOL> """<STR_LIT>""" <EOL> return self . filter ( self . ancestor_of_q ( other , inclusive ) ) <EOL> def not_ancestor_of ( self , other , inclusive = False ) : <EOL> """<STR_LIT>""" <EOL> return self . exclude ( self . ancestor_of_q ( other , inclusive ) ) <EOL> def parent_of_q ( self , other ) : <EOL> return Q ( path = self . model . _get_parent_path_from_path ( other . path ) ) <EOL> def parent_of ( self , other ) : <EOL> """<STR_LIT>""" <EOL> return self . filter ( self . parent_of_q ( other ) ) <EOL> def not_parent_of ( self , other ) : <EOL> """<STR_LIT>""" <EOL> return self . exclude ( self . parent_of_q ( other ) ) <EOL> def sibling_of_q ( self , other , inclusive = True ) : <EOL> q = Q ( path__startswith = self . model . _get_parent_path_from_path ( other . path ) ) & Q ( depth = other . depth ) <EOL> if not inclusive : <EOL> q &= ~ Q ( pk = other . pk ) <EOL> return q <EOL> def sibling_of ( self , other , inclusive = True ) : <EOL> """<STR_LIT>""" <EOL> return self . filter ( self . sibling_of_q ( other , inclusive ) ) <EOL> def not_sibling_of ( self , other , inclusive = True ) : <EOL> """<STR_LIT>""" <EOL> return self . exclude ( self . sibling_of_q ( other , inclusive ) ) <EOL> class PageQuerySet ( SearchableQuerySetMixin , TreeQuerySet ) : <EOL> def live_q ( self ) : <EOL> return Q ( live = True ) <EOL> def live ( self ) : <EOL> """<STR_LIT>""" <EOL> return self . filter ( self . live_q ( ) ) <EOL> def not_live ( self ) : <EOL> """<STR_LIT>""" <EOL> return self . exclude ( self . live_q ( ) ) <EOL> def in_menu_q ( self ) : <EOL> return Q ( show_in_menus = True ) <EOL> def in_menu ( self ) : <EOL> """<STR_LIT>""" <EOL> return self . filter ( self . in_menu_q ( ) ) <EOL> def not_in_menu ( self ) : <EOL> """<STR_LIT>""" <EOL> return self . exclude ( self . in_menu_q ( ) ) <EOL> def page_q ( self , other ) : <EOL> return Q ( id = other . id ) <EOL> def page ( self , other ) : <EOL> """<STR_LIT>""" <EOL> return self . filter ( self . page_q ( other ) ) <EOL> def not_page ( self , other ) : <EOL> """<STR_LIT>""" <EOL> return self . exclude ( self . page_q ( other ) ) <EOL> def type_q ( self , klass ) : <EOL> content_types = ContentType . objects . get_for_models ( * [ <EOL> model for model in apps . get_models ( ) <EOL> if issubclass ( model , klass ) <EOL> ] ) . values ( ) <EOL> return Q ( content_type__in = content_types ) <EOL> def type ( self , model ) : <EOL> """<STR_LIT>""" <EOL> return self . filter ( self . type_q ( model ) ) <EOL> def not_type ( self , model ) : <EOL> """<STR_LIT>""" <EOL> return self . exclude ( self . type_q ( model ) ) <EOL> def exact_type_q ( self , klass ) : <EOL> return Q ( content_type = ContentType . objects . get_for_model ( klass ) ) <EOL> def exact_type ( self , model ) : <EOL> """<STR_LIT>""" <EOL> return self . filter ( self . exact_type_q ( model ) ) <EOL> def not_exact_type ( self , model ) : <EOL> """<STR_LIT>""" <EOL> return self . exclude ( self . exact_type_q ( model ) ) <EOL> def public_q ( self ) : <EOL> from wagtail . wagtailcore . models import PageViewRestriction <EOL> q = Q ( ) <EOL> for restriction in PageViewRestriction . objects . all ( ) : <EOL> q &= ~ self . descendant_of_q ( restriction . page , inclusive = True ) <EOL> return q <EOL> def public ( self ) : <EOL> """<STR_LIT>""" <EOL> return self . filter ( self . public_q ( ) ) <EOL> def not_public ( self ) : <EOL> """<STR_LIT>""" <EOL> return self . exclude ( self . public_q ( ) ) <EOL> def unpublish ( self ) : <EOL> """<STR_LIT>""" <EOL> for page in self . live ( ) : <EOL> page . unpublish ( ) <EOL> def specific ( self ) : <EOL> """<STR_LIT>""" <EOL> if DJANGO_VERSION >= ( <NUM_LIT:1> , <NUM_LIT:9> ) : <EOL> clone = self . _clone ( ) <EOL> clone . _iterable_class = SpecificIterable <EOL> return clone <EOL> else : <EOL> return self . _clone ( klass = SpecificQuerySet ) <EOL> def specific_iterator ( qs ) : <EOL> """<STR_LIT>""" <EOL> pks_and_types = qs . values_list ( '<STR_LIT>' , '<STR_LIT>' ) <EOL> pks_by_type = defaultdict ( list ) <EOL> for pk , content_type in pks_and_types : <EOL> pks_by_type [ content_type ] . append ( pk ) <EOL> content_types = { pk : ContentType . objects . get_for_id ( pk ) <EOL> for _ , pk in pks_and_types } <EOL> pages_by_type = { } <EOL> for content_type , pks in pks_by_type . items ( ) : <EOL> model = content_types [ content_type ] . model_class ( ) <EOL> pages = model . objects . filter ( pk__in = pks ) <EOL> pages_by_type [ content_type ] = { page . pk : page for page in pages } <EOL> for pk , content_type in pks_and_types : <EOL> yield pages_by_type [ content_type ] [ pk ] <EOL> if DJANGO_VERSION >= ( <NUM_LIT:1> , <NUM_LIT:9> ) : <EOL> from django . db . models . query import BaseIterable <EOL> class SpecificIterable ( BaseIterable ) : <EOL> def __iter__ ( self ) : <EOL> return specific_iterator ( self . queryset ) <EOL> else : <EOL> from django . db . models . query import QuerySet <EOL> class SpecificQuerySet ( QuerySet ) : <EOL> iterator = specific_iterator </s>
