我有一个AdminModel,允许用户保存任何留空的字段。但是,当所有字段都为空时,我不希望它们能够保存。我使用以下方法实现了这个:
def save_model(self, request, obj, form, change):
if form.has_changed():
obj.save()
else:
pass
但是,Model与另一个Model有M2M关系,所以当我点击save时出现以下错误:
instance needs to have a primary key value before a many-to-many relationship can be used.
我需要在此方法中添加什么来阻止它尝试创建M2M关系?
修改
我添加了hacky解决方法,但我有兴趣知道是否有更好的方法。解决方法是更改else
,以便更改ModelAdmin的字段属性,使其不包含M2M关系的字段 - 这可以防止它尝试建立关系。这不仅是hacky,而且只有在未能保存模型一次并抛出错误后才能工作......
答案 0 :(得分:3)
你不能在save_m2m
之后调用save_model
。文档特别说这个钩子是not for veto purposes.
ModelAdmin.save_model()和ModelAdmin.delete_model()必须保存/删除 对象,它们不是为了否决的目的,而是它们允许你 执行额外的操作。
您需要的是表单验证以防止save_model
触发。不知何故,您需要检测何时所有字段都留空。
class MyForm(forms.ModelForm):
class Meta:
model = MyModel
def clean(self):
if not any(self.cleaned_data.values()):
raise forms.ValidationError("All fields cannot be blank!")
return self.cleaned_data
class MyAdmin(admin.ModelAdmin):
form = MyForm
答案 1 :(得分:2)
最好在表单级别而不是管理级别进行验证。为此,请创建一个由Form
使用的自定义ModelAdmin
类。因此,请创建forms.py
:
from myapp.models import MyModel
from django import forms
class MyModelForm(forms.ModelForm):
pass
class Meta:
model = MyModel
def clean(self):
empty = True
for field_name, field_data in self.cleaned_data.iteritems():
if field_data:
empty = False
if empty:
raise forms.ValidationError("The form cannot be empty")
return self.cleaned_data
并允许您的管理员使用此表单。在admin.py
:
from myapp.forms import MyModelForm
from django.contrib import admin
class MyModelAdmin(admin.ModelAdmin):
...
form = MyModelForm