def __init__(self, model=None, query=None, using=None, hints=None):
     super(BaseQuerySet, self).__init__(model=model, query=query, using=using, hints=hints)
     self.query = KWQuery(self.model)
     self._iterable_class = ModelIterable
     self.count = 0
     self.low_mark = 0
     self.high_mark = None
     self.result_count = 0
     self.pk_field = self.model._meta.pk
     self._db = self.using
     self.distinct_only = False
     self.filters = []
     self.excludes = []
     self.exclude_args = []
     self.filter_args = []
class BaseQuerySet(QuerySet):

    def __init__(self, model=None, query=None, using=None, hints=None):
        super(BaseQuerySet, self).__init__(model=model, query=query, using=using, hints=hints)
        self.query = KWQuery(self.model)
        self._iterable_class = ModelIterable
        self.count = 0
        self.low_mark = 0
        self.high_mark = None
        self.result_count = 0
        self.pk_field = self.model._meta.pk
        self._db = self.using
        self.distinct_only = False
        self.filters = []
        self.excludes = []
        self.exclude_args = []
        self.filter_args = []

    @classmethod
    def get_manager(cls):
        return type('DictManager', (BaseManager.from_queryset(cls)), {})

    def iterator(self):
        """
        An iterator over the results from applying this QuerySet to the
        database.
        """
        self.results, self.result_count = self.list_objects()
        return iter(self._iterable_class(self))

    def _insert(self, objs, fields, return_id=False, raw=False, using=None):
        self._for_write = True
        self.insert(self.model, fields, objs)
        return self.model
    _insert.alters_data = True
    _insert.queryset_only = False

    def _raw_delete(self, using):
        return self.delete()
    _raw_delete.alters_data = True

    def _filter_or_exclude(self, negate, *args, **kwargs):
        if args or kwargs:
            assert self.can_filter(), \
                "Cannot filter a query once a slice has been taken."

        clone = self._clone()
        if negate:
            clone.exclude_args.append(args)
            clone.excludes.append(kwargs)
        else:
            clone.filter_args.append(args)
            clone.filters.append(kwargs)
        return clone

    def can_filter(self):
        """
        Returns True if adding filters to this instance is still possible.

        Typically, this means no limits or offsets have been put on the results.
        """
        return not self.low_mark and self.high_mark is None

    def distinct(self, *field_names):
        """
        Returns a new QuerySet instance that will select only distinct results.
        """
        assert self.can_filter(), \
            "Cannot create distinct fields once a slice has been taken."
        clone = self._clone()
        clone.distinct_only = True
        return clone

    def reverse(self):
        """
        Reverses the ordering of the QuerySet.
        """

        clone = self._clone()
        clone.decending = not clone.decending
        return clone

    def order_by(self, *field_names):
        """
        Returns a new QuerySet instance with the ordering changed.
        """
        assert self.can_filter(), \
            "Cannot reorder a query once a slice has been taken."
        clone = self._clone()
        field_names = [self.pk_field if x=='pk' else x for x in field_names]
        clone.ordering = field_names
        return clone

    def complex_filter(self, filter_obj):
        Warning("Complex filters have not been implemented for this query type. Received filter_obj:" + str(vars(filter_obj)))

    #Should return number of objects deleted
    def delete(self):
        raise NotImplementedError("""It is required to implement a delete function in custom Queryset
                                    Queryset: %s""" % (vars(self)))

    #Override if a faster delete_batch is available
    def delete_batch(self, pk_list, using, field=None):
        num_deleted = 0
        if not field:
            field = self.pk_field
        for pk in pk_list:
            kwargs = {field: pk}
            if self.filter(**kwargs).delete():
                num_deleted += 1
        return num_deleted

    #Override if a faster update_batch is available
    def update_batch(self, pk_list, values, using):
        field = self.pk_field
        for pk in pk_list:
            kwargs = {field: pk}
            self.filter(**kwargs).update(values)

    #Override if a faster bulk_create is available
    def bulk_create(self, objs, batch_size=None):
        for obj in objs:
            obj.save()

    def insert(self, model, fields, objs):
        raise NotImplementedError("""It is required to implement an insert function in custom QuerySet
                                    Queryset: %s
                                    model: %s
                                    fields: %s
                                    objs: %s""" % (vars(self), model, fields, objs))

    # Must return the total number of objects without filters applied
    def count(self):
        raise NotImplementedError("""It is required to implement a count function in custom Queryset
                                    Queryset: %s""" % (vars(self)))


    # Must return an object list after pagination and a result_count of all objects from before pagination
    def list_objects(self):
        raise NotImplementedError("""It is required to implement a list_objects function in custom Queryset
                                    Queryset: %s""" % (vars(self)))

    #If list_objects does not return a list of model instances, the following needs to be implemented as a final step to convert to a model object
    def to_model(self, model, result):
        if isinstance(result, model):
            return result
        else:
            raise NotImplementedError(
                'It is required to implement a to_model function in custom QuerySet to convert each result to a ' + model._meta.object_name + 'instance')

    def update(self, **kwargs):
        raise NotImplementedError("""It is required to implement an update function in custom QuerySet
                                    Queryset: %s
                                    kwargs: %s""" % (vars(self), str(kwargs)))

    def _update(self, values):
        """
        A version of update that accepts field objects instead of field names.
        Used primarily for model saving and not intended for use by general
        code (it requires too much poking around at model internals to be
        useful at that level).
        """
        assert self.query.can_filter(), \
            "Cannot update a query once a slice has been taken."
        self.update(**values)
    _update.alters_data = True
    _update.queryset_only = False

    def select_for_update(self, nowait=False):
        """
        Returns a new QuerySet instance that will select objects with a
        FOR UPDATE lock.
        """
        clone = self._clone()
        clone._for_write = True
        clone.select_for_update = True
        clone.select_for_update_nowait = nowait
        return clone

    def select_related(self, *fields):
        """
        Returns a new QuerySet instance that will select related objects.
        If fields are specified, they must be ForeignKey fields and only those
        related objects are included in the selection.
        If select_related(None) is called, the list is cleared.
        """

        if self._fields is not None:
            raise TypeError("Cannot call select_related() after .values() or .values_list()")

        obj = self._clone()
        if fields == (None,):
            obj.select_related = False
        elif fields:
            obj.add_select_related(fields)
        else:
            obj.select_related = True
        return obj