管理员中的 Django ModelForm 多次保存
Django ModelForm in admin saving multiple times
我正在尝试实现一个简单的功能,如果您在保存时在管理员中选中了一个复选框,它会发送一封电子邮件。例如:将一篇简单的文章输入到管理员中,当我点击保存时,它会发送文章的内容(如果选中该复选框)。得到了工作,但由于某种原因它发送了 3 次!
这里 post 的代码太多了,但这应该足以了解发生了什么,如果它对夹层博客管理部分(我已经克隆)有帮助的话。
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)
我认为 admin 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 并且每个 class subclasses 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 的文章:
我正在尝试实现一个简单的功能,如果您在保存时在管理员中选中了一个复选框,它会发送一封电子邮件。例如:将一篇简单的文章输入到管理员中,当我点击保存时,它会发送文章的内容(如果选中该复选框)。得到了工作,但由于某种原因它发送了 3 次! 这里 post 的代码太多了,但这应该足以了解发生了什么,如果它对夹层博客管理部分(我已经克隆)有帮助的话。
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)
我认为 admin 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 并且每个 class subclasses 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 的文章: