基于类的通用视图中的ManyToManyField和保存覆盖

时间:2013-05-09 15:34:16

标签: django django-class-based-views django-generic-views

我们有一个基于类的通用视图,它添加了一个具有ManyToManyField关系的对象。我们正在努力 修改在ManyToManyField上创建的关系的save()覆盖上的某些值,但似乎没有 就像他们在save()中创建一样,所以我们不得不在get_success_url中调用post_save方法,以便关系 被创造了。这看起来非常非常难看。在离开save()之前,我们如何强制创建关系?

我见过this answer on SO,它说要覆盖form_valid()来创建关系,但是如果它们是在form_valid()和get_success_url()之间自动创建的,为什么还要这样做? / p>

# 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')

1 个答案:

答案 0 :(得分:0)

如果每次保存Payment时都必须这样做,最好将该责任留给模型而不是将其移动到视图中。最好的方法是使用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。它使你的开发人员更清楚。