Django:保存相关对象后执行操作

时间:2018-07-26 21:57:33

标签: python django django-models

我有两个模型:

class Author(models.Model):
    name = models.CharField(max_length=100)
    create_report = models.BooleanField(default=False)

class Book(models.Model):
    author = models.ForeignKey(Author, on_delete=models.PROTECT)
    title = models.CharField(max_length=100)

他们是这样在管理员中注册的:

class BookInline(admin.TabularInline):
    model = PurchaseOrderItem

@admin.register(PurchaseOrder)
class AuthorAdmin(admin.ModelAdmin):
    inlines = (PurchaseOrderInline,)

我通过Django管理员创建了一个作者和两本书。点击“保存”按钮后,如果Author.create_report == True,我希望看到一个报告,内容如下:

  

作者-无论谁写过以下书:

     
      
  • 第一本书的标题

  •   
  • 第一本书的标题

  •   

(报告应出现在何处或模板的呈现方式与此处无关,请跳过它们。)

我的第一个想法是覆盖Author.save()方法:

def save(self, *args, **kwargs):
    super().save(*args, **kwargs)
    if self.create_report:
        self.write_report(name=self.name, books=self.book_set.all())

问题是Author.save()方法在保存Book个对象之前已执行,因此self.book_set.all()为空。

一种解决方法是使用其他一些ModelAdmin函数(例如log_addition()),该函数会在保存Book个对象后触发,但是我希望使用相同的功能管理员,这也不是最好的解决方案。

在不使用管理层功能的情况下,我能以某种方式获得结果吗?

2 个答案:

答案 0 :(得分:2)

book_set.all()最初为Null,因为在创建作者时没有与Book相关的Author。因此,我的建议是,在创建Book时生成报告

class Author(models.Model):
    name = models.CharField(max_length=100)
    create_report = models.BooleanField(default=False)


class Book(models.Model):
    author = models.ForeignKey(Author, on_delete=models.PROTECT)
    title = models.CharField(max_length=100)

    def save(self, *args, **kwargs):
        pk = self.pk  # pk will be None like objects if self is new instance
        super().save(*args, **kwargs)
        if not pk and self.author.create_report:
            write_report(name=self.author.name, books=self.author.book_set.all())

答案 1 :(得分:0)

我遇到类似的问题。我认为这正是Django引入信号的原因。您可以触发并捕获创建的“书籍/作者”的信号,然后从那里触发创建某种报告的操作。

但是我明白你的意思了(因为我也有同样的痛苦)... id很棒,因为它可以直接从模型中使用。