Django Manager и QuerySets: Как я могу настроить менеджер и запрос для получения Parent ForeignKey ID в models.Queryset для построения каталога папок?

Как я могу извлечь родительские ForeignKey IDs из ManyToManyFields менеджера для построения пути, по которому я могу построить каталог папок?

Я могу сделать запрос в оболочке, чтобы получить ID родителя. Выходит Board.id = 1, что правильно

In [37]: _id = Column.objects.all()

In [38]: _id[0].board.id
Out[38]: 1

если я пытаюсь воспроизвести в Manager, то получаю ошибку

TypeError: 'ForeignKeyDeferredAttribute' object is not callable

Итак, как только создается доска, создается папка, как вы можете видеть в модели Board Model. Теперь у меня есть дочерняя модель под названием Column, которая имеет поле ForeignKey из Board. Цель - создать дочернюю подпапку в каталоге, как только модель Column сохранится. Поэтому модель должна найти ID родителя и добавить Column.id в относительный путь

Поэтому я считаю, что по логике я должен запросить внешний ключ в модели Column и построить относительный путь, как описано в ColumnQuerySet.

Короче говоря, как я могу создать подкаталог папки? Есть идеи? Спасибо за любую помощь.

Model.py

class Board(models.Model):
    name = models.CharField(max_length=50)
    owner = models.ForeignKey(
        User, on_delete=models.PROTECT, related_name="owned_boards"
    )
    members = models.ManyToManyField(User, related_name="boards")
      
    
    class Meta:
        ordering = ["id"]

    def __str__(self):
        return self.name
    
    def save(
        self, force_insert=False, force_update=False, using=None, update_fields=None
    ):
        is_new = self.pk is None
        super().save(force_insert, force_update, using, update_fields)
        if is_new:
            self.members.add(self.owner)

    def send_signal(self):
        signals.post_save.connect(sender=self, receiver = mkdir_board)
    

@receiver(post_save, sender = Board)
def mkdir_board(sender, instance ,**kwargs):
        rel_path = "boards/Files/{}".format(instance.id)
        # path = os.path.join(settings.Media_ROOT)
        try:
            os.makedirs(rel_path)
        except OSError as exc:  # Python ≥ 2.5
            if exc.errno == errno.EEXIST and os.path.isdir(rel_path):
                pass
                    # possibly handle other errno cases here, otherwise finally:
            else:
                raise

class Column(SortableMixin):
    title = models.CharField(max_length=255)
    board = models.ForeignKey("Board", related_name="columns", on_delete=models.CASCADE)
    column_order = models.PositiveIntegerField(default=0, editable=False, db_index=True)
    path = models.CharField(max_length=200)
    objects = Column_Manager()
    
    class Meta:
        ordering = ["column_order"]
        
    def __str__(self):
        # return board_id
        return f"{self.title} + {self.board.id} + {self.id}"   

    def save(
        self, force_insert=False, force_update=False, using=None, update_fields=None
    ):
        is_new = self.pk is None
        super().save(force_insert, force_update, using, update_fields)

managers.py

from django.db import models
import os
import errno

class ColumnQuerySet(models.QuerySet):
    def column_mkdir(self, board, **kwargs):
        _id = self.objects.all()
        board_id = _id[self].board.id
        column_id = _id[self].id
        rel_path = "boards/Files/{board_id}/{column_id}"
       
        try:
            os.makedirs(rel_path)
        except OSError as exc:  # Python ≥ 2.5
            if exc.errno == errno.EEXIST and os.path.isdir(rel_path):
                pass
                        # possibly handle other errno cases here, otherwise finally:
            else:
                raise
      
    
class Column_Manager(models.Manager):
    def get_queryset(self,**kwargs):
        return ColumnQuerySet(self.model,  using=self._db)
        #return super(ActiveAccountsManager, self).get_queryset().filter(user__is_active=True)
    def board_id(self, board):
        qs = self.get_queryset
        _id = qs.objects.all()
        board_id = _id[self].board.id
        return str(self.board_id)
    def column_id(self):
        _id = self.objects.all()
        column_id = _id[self].id
        return self.column_id
Вернуться на верх