1

我们有一个基于类的通用视图,它添加了一个具有 ManyToManyField 关系的对象。我们正在尝试为在该 ManyToManyField 上创建的关系修改 save() 覆盖上的一些值,但似乎它们从未在 save() 中创建,因此我们被迫在 get_success_url 中调用 post_save 方法,所以关系被创建。这看起来非常非常丑陋。我们如何在离开 save() 之前强制创建关系?

在 SO 上看到了这个答案,它说要覆盖 form_valid() 来创建关系,但是如果它们是在 form_valid() 和 get_success_url() 之间的某个位置自动创建的,为什么我需要这样做?

# models.py
class Payment(models.Model):
    invoice = models.ManyToManyField(Invoice)
    deposit_date = models.DateField()
    check_number = models.CharField(max_length=100, blank=True, null=True)
    description = models.TextField(blank=True, null=True)

    def post_save(self):
        """
        ManyToManyField relationships aren't formed yet when overriding save() for Class Based Generic
        Views. Call this whenever you're saving a Payment object.
        """
        for invoice in self.invoice.all():
            # Do some calcualtions that make us happy
            invoice.save()

# views.py - We override get_success_url() in UpdateView too.
class PaymentAdd(CreateView):
    model = Payment
    form_class = PaymentForm
    context_object_name = 'object'
    template_name = 'form.html'

    def get_success_url(self):
        self.object.post_save()
        return reverse('payment-page')
4

1 回答 1

0

如果每次Payment保存 a 时都必须这样做,那么最好将该责任留给模型而不是将其移动到视图中。最好的方法是使用post_save信号,如下所示:

models.py中,低于Payment模型定义的某处:

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

@receiver(post_save, sender=Payment)
def my_handler(sender, instance, **kwargs):
    for invoice in instance.invoice.all():
        # Do some calcualtions that make us happy
        invoice.save()

在不相关的说明中,我强烈建议您对 M2M 字段使用复数属性名称:invoices而不是invoice在这种情况下。它使您的开发人员更清楚。

于 2013-05-11T15:24:30.250 回答