Вызовите метод для каждого экземпляра модели - PullRequest
2 голосов
/ 14 октября 2019

У меня есть Category модель. Я хочу сделать каталог для категории каждый раз, когда я создаю новую категорию. У меня есть метод в моей модели под названием create_directory.

class Category(models.Model):
    category_title = models.CharField(max_length=200)
    category_image = models.ImageField(upload_to="category")
    category_description = models.TextField()
    slug = models.SlugField(max_length=200, unique=True, default=1)

    def create_directory(self):
        gallery_path = os.path.abspath(
            os.path.join(settings.MEDIA_ROOT, Category.slug))
        if not os.path.isdir(gallery_path):
            os.mkdir(gallery_path)

    class Meta:
        verbose_name_plural = "Categories"
        unique_together = ("category_title", "slug")

    def __str__(self):
        return self.category_title

Я хочу звонить create_directory каждый раз, когда создаю категорию в панели администратора.

Ответы [ 2 ]

2 голосов
/ 14 октября 2019

Во-первых, я думаю, что вы имели в виду self.slug, а не Category.slug. self.slug - это значение поля slug для данного конкретного экземпляра , в то время как Category.slug - просто экземпляр класса SlugField.

Вам следует переопределить save вашей модели. метод для вызова create_directory:

class Category(models.Model):
    ...

    def create_directory(self):
        gallery_path = os.path.abspath(
            os.path.join(settings.MEDIA_ROOT, self.slug))
        if not os.path.isdir(gallery_path):
            os.mkdir(gallery_path)

    def save(self, *args, **kwargs):
        if not self.pk:
            self.create_directory()
        super().save(*args, **kwargs)

В качестве альтернативы вы можете создать сигнал для этого:

models.py:

from django.db.models.signals import post_save
from django.dispatch import receiver

@receiver(post_save, sender=Category)
def category_post_save(sender, instance, *args, **kwargs):
    gallery_path = os.path.abspath(
        os.path.join(settings.MEDIA_ROOT, instance.slug))
    if not os.path.isdir(gallery_path):
        os.mkdir(gallery_path)

Обновление

Если вы также хотите удалить каталог, вы можете переопределить метод delete:

class Category(models.Model):
    ...

    def delete(self, *args, **kwargs):
        os.rmdir(os.path.join(settings.MEDIA_ROOT, self.slug))
        super().delete(*args, **kwargs)

Также имеется сигнал pre_deleteчто вы можете использовать.

0 голосов
/ 14 октября 2019

Я хочу вызывать create_directory каждый раз, когда создаю категорию на панели администратора.

Как вы хотите вызывать метод create_directory, когда категория создается из admin panel, вы должны использовать save_model , а не save .

Возможно, вы захотите прочитать Разница между save () и save_model () .

Просто вы можете сделать:

def save_model(self, request, obj, form, change):
    self.create_directory()
    super().save_model(request, obj, form, change)
...