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