2016-07-15 143 views
1

在管理站点中,我有一个自定义窗体。但是,我想重写save方法,以便如果输入某个关键字,则不会将其保存到数据库中。这可能吗?Django管理站点修改保存

class MyCustomForm (forms.ModelForm): 

    def save(self, commit=True): 
     input_name = self.cleaned_data.get('input_name', None) 
     if input_name == "MyKeyword": 
      //Do not save 
     else: 
      return super(MyCustomForm, self).save(commit=commit) 

但这返回错误:

AttributeError 'NoneType' object has no attribute 'save' 

编辑 在此之后:Overriding the save method in Django ModelForm

我想:

def save(self, force_insert=False, force_update=False, commit=True): 
    m = super(MyCustomCategoryForm, self).save(commit=False) 
    input_name = self.cleaned_data.get('input_name', None) 
    if input_name != "MyKeyword": 
     m.save() 
    return m  

但是,管理工具仍然会创建一个新的输入如果输入_name是“我的关键字”

+0

那么这个代码有什么问题?你可以简化它改变条件为'if input_name!=“MyKeyword”:super(MyCustomForm,self).save(commit = commit)',但除此之外它应该像你写的那样工作。 – xbello

+0

我试过,但错误是:AttributeError'NoneType'对象没有'保存'属性 – Rueen1963

+0

然后,也许你的ModelForm没有返回被保存的对象:它返回“None”。阅读这个答案http://stackoverflow.com/a/817364/1688590。 – xbello

回答

1

save()方法应该返回对象,无论是否保存。它更应是这样的:

def save(self, commit=True): 
    input_name = self.cleaned_data.get('input_name') 
    if input_name == "MyKeyword": 
     commit = False 
    return super().save(commit=commit) 

然而,正如你可以看到herehere,形式已经被称为与commit=False和对象是由您ModelAdminsave_model()方法后保存。这就是你得到AttributeError 'NoneType' object has no attribute 'save'的原因。如果你检查异常的回溯,我很确定这个错误来自this line

因此,你应该,另外,覆盖您ModelAdminsave_model()方法:

def save_model(self, request, obj, form, change): 
    if form.cleaned_data.get('input_name') == 'MyKeyword': 
     return # Don't save in this case 
    super().save_model(request, obj, form, change) 

# And you'll also have to override the `ModelAdmin`'s `save_related()` method 
# in the same flavor: 

def save_related(self, request, form, formsets, change): 
    if form.cleaned_data.get('input_name') == 'MyKeyword': 
     return # Don't save in this case 
    super().save_related(request, form, formsets, change) 

鉴于此回答您的评论

It is working now but I just have one related question. The admin site will still display a green banner at the top saying "The model was added successfully". Can I override some method so that it is red and says "The model already exists"?

它看起来就是你想要的要做的不是重写保存方法,而是controlling form validation。这是完全不同的。您只需重写表单的干净方法。

from django import forms 

def clean(self): 
    """ 
    super().clean() 
    if self.cleaned_data.get('input_name') == 'MyKeyword': 
     raise forms.ValidationError("The model already exists") 

,或者甚至更好,因为它看起来像你想clean a single field

from django import form 

def clean_input_name(self): 
    data = self.cleaned_data['input_name'] 
    if data == 'MyKeyWord': 
     raise forms.ValidationError("The model already exists") 

然而,我猜input_name也是模型的一个领域,你不想提这个仅在一个表单上出现错误,但是在整个项目中出错在这种情况下,你在找什么是Model validators

from django.core.exceptions import ValidationError 

def validate_input_name(value): 
    if value == 'MyKeyword': 
     raise ValidationError("The model already exists") 
+0

它现在正在工作,但我只有一个相关的问题。管理网站仍然会在顶部显示绿色横幅,标题为“模型已成功添加”。我可以重写一些方法,使它是红色的,并说“模型已经存在”? – Rueen1963

+0

当然可以。但它看起来确实不是你想要做的。你为什么不从一开始就说你想控制表单验证?请参阅[什么是XY问题](http://meta.stackexchange.com/questions/66377/what-is-the-xy-problem)和我的答案中的更新。另外,当'input_name'设置为**关键字**时,你真的想提出一个错误吗?或者是**变量?**也许**关键字列表** **也许从数据库中检索数据** **也许你只是希望这个字段是**唯一的**如果是这样,为什么你是努力隐藏你的问题的关键信息? –