【问题标题】:Django: perform action after related objects are savedDjango:保存相关对象后执行操作
【发布时间】:2018-07-26 21:57:33
【问题描述】:

我有两个模型:

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 admin 创建了一个作者和两本书。在我点击“保存”按钮后,如果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 对象被保存后触发,但我也希望在管理员之外使用相同的功能,它是不是最好的解决方案。

在不使用管理层函数的情况下,我能以某种方式达到结果吗?

【问题讨论】:

  • 不应该author = models.ForeignKey(Seller, on_delete=models.PROTECT)author = models.ForeignKey(Author, on_delete=models.PROTECT)
  • 你是对的。感谢您指出。

标签: python django django-models


【解决方案1】:

book_set.all() 最初将是Null,因为在作者创建时没有与Author 相关的Book。所以,我的建议是,在创建 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())

【讨论】:

  • 感谢您的建议!我在某些情况下使用这种方法,但在这里它并不能真正满足需求。在上述情况下,您的解决方案将显示两个报告,但问题是当且仅当所有书籍都已保存时,我才需要显示报告一次。你对此有什么建议吗?
【解决方案2】:

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

但是我明白你的意思(因为我也有同样的痛苦)......如果这可以直接从模型中工作,那就太好了。

【讨论】:

    猜你喜欢
    • 2021-06-14
    • 2021-02-13
    • 2010-11-30
    • 2016-01-05
    • 2017-04-12
    • 1970-01-01
    • 1970-01-01
    • 2020-09-03
    • 2015-02-15
    相关资源
    最近更新 更多