示例#1
0
 def get_as_specialization(self, final_specialization=True):
     """
     Get the specialized model instance which corresponds to the general
     case.
     
     :param final_specialization: Whether the specialization returned is
         the most specialized specialization or whether the direct
         specialization is used
     :type final_specialization: :class:`bool`
     :return: The specialized model corresponding to the current model
     
     """
     
     path = self.specialization_type
     
     if not final_specialization:
         # We need to find the path which is only one-step down from the
         # current level of specialization.
         path = find_next_path_down(
             self._meta.specialization, path, PATH_SEPERATOR
             )
 
     return self._meta.specializations[path].objects.get(
         pk=self.pk
         )
示例#2
0
    def iterator(self):
        """
        Override the iteration to ensure what's returned are Specialized Model
        instances.

        """

        # Determine whether there are any extra fields which are also required
        # to order the queryset. This is needed as Django's implementation of
        # ValuesQuerySet cannot cope with fields being omitted which are used in
        # the ordering and originating from an extra select
        extra_fields = set(self.query.extra.keys())
        ordering_fields = set(field.lstrip("-") for field in self.query.order_by)
        extra_ordering_fields = list(extra_fields & ordering_fields)

        values_query_fields = ["specialization_type", "id"] + extra_ordering_fields

        # Get the resource ids and types together
        specializations_data = self._clone().values(*values_query_fields)

        # Transform this into a dictionary of IDs by type:
        ids_by_specialization = defaultdict(list)

        # and keep track of the IDs which respect the ordering specified in the
        # queryset:
        specialization_ids = []

        for specialization_data in specializations_data:
            specialization_type = specialization_data["specialization_type"]
            specialization_id = specialization_data["id"]

            ids_by_specialization[specialization_type].append(specialization_id)
            specialization_ids.append(specialization_id)

        specialized_model_instances = {}

        # Add the sub-class instances into a single look-up
        for specialization, ids in ids_by_specialization.items():
            if not self._final_specialization:
                # Coerce the specialization to only be the direct child of the
                # general model (self.model):
                specialization = find_next_path_down(self.model.model_specialization, specialization, PATH_SEPERATOR)

            sub_queryset = self.model._meta.specializations[specialization].objects.all()

            # Copy any deferred loading over to the new querysets:
            sub_queryset.query.deferred_loading = self.query.deferred_loading

            # Copy any extra select statements to the new querysets. NB: It
            # doesn't make sense to copy any of the "where", "tables" or
            # "order_by" options as these have already been applied in the
            # parent queryset
            sub_queryset.query._extra = self.query._extra

            sub_instances = sub_queryset.in_bulk(ids)

            specialized_model_instances.update(sub_instances)

        for resource_id in specialization_ids:
            yield specialized_model_instances[resource_id]
示例#3
0
    def get(self, *args, **kwargs):
        """
        Override get to ensure a specialized model instance is returned.

        :return: A specialized model instance

        """

        if "specialization_type" in kwargs:
            # if the specialization is explicitly specified, use this to work out
            # which sub-class of the general model we'll use:
            specialization = kwargs.pop("specialization_type")
        else:
            try:
                specialization = (
                    super(SpecializedQuerySet, self)
                    .filter(*args, **kwargs)
                    .values_list("specialization_type", flat=True)[0]
                )
            except IndexError:
                raise self.model.DoesNotExist("%s matching query does not exist." % self.model._meta.object_name)

        if not self._final_specialization:
            # Coerce the specialization to only be the direct child of the
            # general model (self.model):
            specialization = find_next_path_down(self.model.model_specialization, specialization, PATH_SEPERATOR)

        try:
            return self.model._meta.specializations[specialization].objects.get(*args, **kwargs)
        except KeyError:
            raise self.model.DoesNotExist("%s matching query does not exist." % self.model._meta.object_name)
示例#4
0
    def test_non_root(self):
        """Test the path below a non-root path can be identified correctly"""

        non_root = '/home/'
        full_path = '/home/barry/dev/'

        eq_(find_next_path_down(non_root, full_path, '/'), '/home/barry/')
示例#5
0
    def test_root_down(self):
        """Test the path below the root path can be identified correctly."""

        root = '/'
        full_path = '/home/barry/dev/'

        eq_(find_next_path_down(root, full_path, '/'), '/home/')
示例#6
0
 def iterator(self):
     """
     Override the iteration to ensure what's returned are Specialized Model
     instances.
     
     """
     
     # Get the resource ids and types together:
     specializations_by_id = self._clone().values_list(
         'specialization_type', 'id'
         )
     
     # Transform this into a dictionary of IDs by type:
     ids_by_specialization = defaultdict(list)
     
     # and keep track of the IDs which respect the ordering specified in the
     # queryset:
     specialization_ids = []
     
     for specialization, id in specializations_by_id:
         ids_by_specialization[specialization].append(id)
         specialization_ids.append(id) 
     
     specialized_model_instances = {}
     
     # Add the sub-class instances into a single look-up 
     for specialization, ids in ids_by_specialization.items():
         if not self._final_specialization:
             # Coerce the specialization to only be the direct child of the
             # general model (self.model):
             specialization = find_next_path_down(
                 self.model._meta.specialization, specialization,
                 PATH_SEPERATOR
                 )
         
         sub_queryset = self.model._meta.specializations[
             specialization
             ].objects.all()
             
         # Copy any deferred loading over to the new querysets:
         sub_queryset.query.deferred_loading = self.query.deferred_loading 
         
         sub_instances = sub_queryset.in_bulk(ids)
         
         specialized_model_instances.update(sub_instances)
     
     for resource_id in specialization_ids:
         yield specialized_model_instances[resource_id]
示例#7
0
    def iterator(self):
        """
        Override the iteration to ensure what's returned are Specialized Model
        instances.
        
        """

        # Get the resource ids and types together:
        specializations_by_id = self._clone().values_list(
            'specialization_type', 'id')

        # Transform this into a dictionary of IDs by type:
        ids_by_specialization = defaultdict(list)

        # and keep track of the IDs which respect the ordering specified in the
        # queryset:
        specialization_ids = []

        for specialization, id in specializations_by_id:
            ids_by_specialization[specialization].append(id)
            specialization_ids.append(id)

        specialized_model_instances = {}

        # Add the sub-class instances into a single look-up
        for specialization, ids in ids_by_specialization.items():
            if not self._final_specialization:
                # Coerce the specialization to only be the direct child of the
                # general model (self.model):
                specialization = find_next_path_down(
                    self.model.model_specialization, specialization,
                    PATH_SEPERATOR)

            sub_queryset = self.model._meta.specializations[
                specialization].objects.all()

            # Copy any deferred loading over to the new querysets:
            sub_queryset.query.deferred_loading = self.query.deferred_loading

            sub_instances = sub_queryset.in_bulk(ids)

            specialized_model_instances.update(sub_instances)

        for resource_id in specialization_ids:
            yield specialized_model_instances[resource_id]
示例#8
0
    def get_as_specialization(self, final_specialization=True):
        """
        Get the specialized model instance which corresponds to the general
        case.

        :param final_specialization: Whether the specialization returned is
            the most specialized specialization or whether the direct
            specialization is used
        :type final_specialization: :class:`bool`
        :return: The specialized model corresponding to the current model

        """

        path = self.specialization_type

        if not final_specialization:
            # We need to find the path which is only one-step down from the
            # current level of specialization.
            path = find_next_path_down(self.__class__.model_specialization,
                                       path, PATH_SEPERATOR)

        return self._meta.specializations[path].objects.get(pk=self.pk)
示例#9
0
    def get(self, *args, **kwargs):
        """
        Override get to ensure a specialized model instance is returned.
        
        :return: A specialized model instance
        
        """

        if 'specialization_type' in kwargs:
            # if the specialization is explicitly specified, use this to work out
            # which sub-class of the general model we'll use:
            specialization = kwargs.pop('specialization_type')
        else:
            try:
                specialization = super(SpecializedQuerySet, self)\
                    .filter(*args, **kwargs).values_list(
                        'specialization_type', flat=True
                        )[0]
            except IndexError:
                raise self.model.DoesNotExist(
                    "%s matching query does not exist." %
                    self.model._meta.object_name)

        if not self._final_specialization:
            # Coerce the specialization to only be the direct child of the
            # general model (self.model):
            specialization = find_next_path_down(
                self.model.model_specialization, specialization,
                PATH_SEPERATOR)

        try:
            return self.model._meta.specializations[specialization]\
                                   .objects.get(*args, **kwargs)
        except KeyError:
            raise self.model.DoesNotExist("%s matching query does not exist." %
                                          self.model._meta.object_name)