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