Django ModelForm在admin中多次保存

时间:2015-11-19 12:23:10

标签: django mezzanine

我正在尝试实现一个简单的函数,如果在保存时在管理员中选中了复选框,则会发送电子邮件。例如:输入一个简单的文章,当我点击保存它发送文章的内容(如果复选框被选中)。得到那个工作,但由于某种原因,它发送3次! 在这里发布的代码太多了,但这应该足以看到发生了什么,如果它有助于其中一些,如果来自夹层博客管理部分(我克隆了)。

class YourModelForm(forms.ModelForm):
    send_email = forms.BooleanField(required=False)
    def save(self, commit=True):
        send_email = self.cleaned_data.get('send_email', None)
        content = self.cleaned_data.get('content', None)
        if send_email == True:
            print 'sending' #email stuff here 
        return super(YourModelForm, self).save(commit=commit)

    class Meta:
        model = Ite
        fields = '__all__'

class IteAdmin(TweetableAdminMixin, DisplayableAdmin, OwnableAdmin):
    form = YourModelForm
    readonly_fields=('email_sent',)
    fieldsets = ite_fieldsets 


    def save_form(self, request, forms, change):
        """
        Super class ordering is important here - user must get saved first.
        """
        OwnableAdmin.save_form(self, request, forms, change)
        return DisplayableAdmin.save_form(self, request, forms, change)

1 个答案:

答案 0 :(得分:1)

我不认为管理员ModelForm是触发邮件发送的好地方。 我建议使用这样的信号:

from django.db.models.signals import post_save

class MyModel(models.Model):
    ...


def send_mail_for_my_model(sender, instance, created, **kwargs):
    if created:
        print "send mail"
        #email stuff

post_save.connect(send_mail_for_my_model, sender=MyModel)

我想你的情况: OwnableAdmin.save_form()调用YourModelForm.save,从而发送邮件。 比DisplayableAdmin.save_form()调用YourModelForm.save,再次发送邮件。 发生这种情况是因为save_form(self)的第一个参数是IteAdmin的实例,其form属性设置为YourModelForm,每个类都是ModelAdmin的子类。

如果你想使用ModelForm,我猜你应该使用这样的方法:

class OwnableAdmin(ModelAdmin):
    def save_form(self, request, forms, change):
        #do your actions
        return super(OwnableAdmin, self).save_form(request, forms, change)


class DisplayableAdmin(ModelAdmin):
    def save_form(self, request, forms, change):
        #do your actions
        return super(DisplayableAdmin, self).save_form(request, forms, change)


class TweetableAdminMixin(object):
    ...    


class IteAdmin(OwnableAdmin, DisplayableAdmin, TweetableAdminMixin):
    form = YourModelForm
    readonly_fields=('email_sent',)
    fieldsets = ite_fieldsets 

    def save_form(self, request, forms, change):
        #do your actions
        return super(IteAdmin, self).save_form(request, forms, change)

顺便说一句,在python3中你可以使用不带参数的super()。

也许在你的情况下,每个模特都可以继承其他模特,如:

class TweetableAdmin(ModelAdmin):
    ...

class DisplayableAdmin(TweetableAdmin):
    ...


class OwnableAdmin(DisplayableAdmin):
    ...

class IteAdmin(OwnableAdmin):
    ...

无论如何,我建议阅读有关python super的文章:

http://www.artima.com/weblogs/viewpost.jsp?thread=236275