2016-07-15 170 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'設置爲**關鍵字**時,你真的想提出一個錯誤嗎?或者是**變量?**也許**關鍵字列表** **也許從數據庫中檢索數據** **也許你只是希望這個字段是**唯一的**如果是這樣,爲什麼你是努力隱藏你的問題的關鍵信息? –