class RelatedManager( create_reverse_many_to_one_manager( related_model._default_manager.__class__, self.rel, )): @sync_to_async_threadsafe def async_async_create(self, **kwargs): self.create(**kwargs) @sync_to_async_threadsafe def async_get_or_create(self, **kwargs): self.get_or_create(**kwargs) @sync_to_async_threadsafe def async_update_or_create(self, **kwargs): return self.update_or_create(**kwargs) @sync_to_async_threadsafe def async_clear(self, *, bulk=True): self.clear(bulk=bulk) @sync_to_async_threadsafe def async_set(self, objs, *, bulk=True, clear=False): return self.set(objs, bulk=bulk, clear=clear) @sync_to_async_threadsafe def async_remove(self, *args, **kwargs): return self.remove(*args, **kwargs) @sync_to_async_threadsafe def async_add(self, *args, **kwargs): return self.add(*args, **kwargs)
def _create_reverse_many_to_one_manager(*args, **kwargs): context = inspect.getcallargs(create_reverse_many_to_one_manager, *args, **kwargs) manager = create_reverse_many_to_one_manager(*args, **kwargs) manager.get_queryset = signalify_queryset( manager.get_queryset, parser=parse_foreign_related_queryset, **context) return manager
def related_manager_cls(self): ''' Copied from ReverseManyToOneDescriptor.related_manager_cls, Replace self.rel.related_model._default_manager.__class__ by self.get_manager_base_class() ''' return create_reverse_many_to_one_manager( self.get_manager_base_class(), # CHANGE self.rel, )
def _create_reverse_many_to_one_manager(*args, **kwargs): context = inspect.getcallargs(create_reverse_many_to_one_manager, *args, **kwargs) manager = create_reverse_many_to_one_manager(*args, **kwargs) manager.get_queryset = signalify_queryset( manager.get_queryset, parser=parse_foreign_related_queryset, **context ) return manager
def create_reverse_cdms_many_to_one_manager(superclass, rel): subclass = create_reverse_many_to_one_manager( superclass, rel ) class RelatedManager(subclass): def __init__(self, *args, **kwargs): super(RelatedManager, self).__init__(*args, **kwargs) self.cdms_skip = False def __call__(self, **kwargs): # We use **kwargs rather than a kwarg argument to enforce the # `manager='manager_name'` syntax. manager = getattr(self.model, kwargs.pop('manager')) manager_class = create_reverse_cdms_many_to_one_manager(manager.__class__, rel) return manager_class(self.instance) do_not_call_in_templates = True def skip_cdms(self): """ Needs to be redefined because of Django madness :-| """ self.cdms_skip = True return self def get_queryset(self): qs = super(RelatedManager, self).get_queryset() qs.cdms_skip = self.cdms_skip qs._cdms_known_related_objects = {self.field.name: {self.instance.cdms_pk: self.instance}} return qs def add(self, *args, **kwargs): raise NotImplementedError() def create(self, *args, **kwargs): raise NotImplementedError() def get_or_create(self, *args, **kwargs): raise NotImplementedError() def update_or_create(self, *args, **kwargs): raise NotImplementedError() def remove(self, *args, **kwargs): raise NotImplementedError() def clear(self, *args, **kwargs): raise NotImplementedError() return RelatedManager
def get_children(self, manager): """ This method allows us to call with a manger instance or a string i.e both: obj.get_children('private_objects') and obj.get_children(Election.public_objects) are supported. This will return a 'children' RelatedManager with the relevant filters applied. """ for m in self._meta.managers: if m.name == manager or m == manager: child_manager_cls = create_reverse_many_to_one_manager( m.__class__, self._meta.get_field("_children_qs")) return child_manager_cls(self) raise ValueError("Unknown manager {}".format(manager))
def related_manager_cls(self): related_model = self.rel.related_model RelatedManager = create_reverse_many_to_one_manager( related_model._default_manager.__class__, self.rel, ) class StrictRelatedManager(RelatedManager): def get_prefetch_queryset(self, instances, queryset=None): """Reimplemented to avoid a call to __iter__""" if queryset is None: queryset = super(RelatedManager, self).get_queryset() queryset._add_hints(instance=instances[0]) queryset = queryset.using(queryset._db or self._db) rel_obj_attr = self.field.get_local_related_value instance_attr = self.field.get_foreign_related_value instances_dict = { instance_attr(inst): inst for inst in instances } query = {'%s__in' % self.field.name: instances} queryset = queryset.filter(**query) # Since we just bypassed this class' get_queryset(), we must manage # the reverse relation manually. result = queryset.to_list() for rel_obj in result: instance = instances_dict[rel_obj_attr(rel_obj)] setattr(rel_obj, self.field.name, instance) cache_name = self.field.related_query_name() return result, rel_obj_attr, instance_attr, False, cache_name return StrictRelatedManager
def create_foreign_related_manager(superclass, rel_field, rel_model): return create_reverse_many_to_one_manager( superclass, ReverseForeignRelatedObjectsRel(rel_field, rel_model))
def create_foreign_related_manager(superclass, rel_field, rel_model): return create_reverse_many_to_one_manager( superclass, ReverseForeignRelatedObjectsRel(rel_field, rel_model))