为每个模型实例调用一个方法

时间:2019-10-14 04:18:17

标签: django django-models

我有一个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 个答案:

答案 0 :(得分:2)

首先,我认为您的意思是self.slug,而不是Category.slugself.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)

或者,您可以为此创建一个signal

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信号可供您使用。

答案 1 :(得分:0)

  

每次在“管理”面板中创建类别时,我都想调用create_directory。

create_directory创建类别时,要调用admin panel方法,应使用save_model而不是save

您可能想阅读Difference between save() and save_model()

您可以做到:

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