У меня есть модель, которая ссылается на себя через вторую модель отношений:
...
class Branch(models.Model):
length = models.PositiveSmallIntegerField()
objects = BranchQueryset.as_manager() # Defined below
@property
def branches(self):
if self._branches:
branch_pks = [branch.child_branch.pk for branch in self._branches.all()]
return Branch.objects.filter(pk__in=branch_pks)
return None
class Branches(models.Model):
parent_branch = models.ForeignKey(Branch, related_name='_branches', on_delete=models.CASCADE)
child_branch = models.ForeignKey(Branch, on_delete=models.SET_NULL)
order = models.PositiveSmallIntegerField()
Таким образом, если branch
является некоторым экземпляром Branch
, branch.branches
вернет набор запросов из Branch
объектов, которые ответвляются от branch
. ;)
Проблема заключается в следующем:
class BranchQueryset(models.QuerySet):
def get_trunks(self):
return self.filter(branches_set__isnull=True)
Если я позвоню Branch.objects.get_trunks()
, я получу ошибку django.core.exceptions.FieldError: Cannot resolve keyword 'branches_set' into field. Choices are: _branches, length, id, step
. Итак, мой пользовательский набор запросов не может получить доступ к связанным объектам. Я думаю это как-то связано с этим :
Использование менеджеров для доступа к связанным объектам
По умолчанию Django использует экземпляр класса менеджера Model._base_manager при доступе к связанным объектам (например, choice.question), а не _default_manager в связанном объекте. Это связано с тем, что Django должен иметь возможность извлекать связанный объект, даже если он иначе будет отфильтрован (и, следовательно, недоступен) менеджером по умолчанию.
Но мне не удалось заставить что-либо работать, создав менеджера (я надеялся, что смогу импортировать что-то вроде models.RelatedManager
).
Как я могу получить доступ и отфильтровать branches_set
в моем пользовательском наборе запросов?
Редактировать: Я пытался сделать что-то вроде этого, вместо этого:
class BranchManager(models.Manager):
def get_trunks(self):
return self.get_queryset().filter(branches_set__isnull=True)
class Branch(models.Model):
...
objects = BranchManager()
Но это не сработало.