The save()
method is supposed to return the object, whether saved or not. It should rather look like:
def save(self, commit=True):
input_name = self.cleaned_data.get('input_name')
if input_name == "MyKeyword":
commit = False
return super().save(commit=commit)
However, as you can see here and here, the form is already called with commit=False
and the object is saved later by the save_model()
method of your ModelAdmin
. This is the reason why you got AttributeError 'NoneType' object has no attribute 'save'
. If you check the traceback of the exception, I'm pretty sure the error comes from this line.
Thus you should, in addition, override your ModelAdmin
's save_model()
method:
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)
Given your comment in this answer
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"?
It looks that what you want to do is not overriding the save method but controlling form validation. Which is completely different. You just have to override your form's clean method.
from django import forms
def clean(self):
"""
super().clean()
if self.cleaned_data.get('input_name') == 'MyKeyword':
raise forms.ValidationError("The model already exists")
Or, even better since it looks like you want to 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")
However, I guess input_name
is also a field of your model and you don't want to raise this error only on one form but across all your project. In which case, what you are looking for are Model validators:
from django.core.exceptions import ValidationError
def validate_input_name(value):
if value == 'MyKeyword':
raise ValidationError("The model already exists")