2016-07-15 3 views
1

На административном сайте у меня есть пользовательская форма. Однако я хочу переопределить метод сохранения, чтобы, если введено определенное ключевое слово, я не сохраняю его в базе данных. Это возможно?Django admin site modify save

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 is «MyKeyword»

+0

Так что не так с этим кодом? Вы можете упростить его, изменив условие на 'if input_name! =" MyKeyword ": super (MyCustomForm, self) .save (commit = commit)', но кроме этого он должен работать так, как вы его написали. – xbello

+0

Я пробовал это, но ошибка: AttributeError 'NoneType' объект не имеет атрибута 'save' – 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) 

Однако, как вы можете видеть here и here, форма уже вызывается с commit=False и объект сохраняется позже в save_model() метод вашего ModelAdmin. Вот почему вы получили AttributeError 'NoneType' object has no attribute 'save'. Если вы проверите трассировку исключения, я уверен, что ошибка исходит от this line.

Таким образом, вы должны, кроме того, переопределить ваш ModelAdmin «ы save_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' установлен на ** ключевое слово **? Или ** переменная? ** Может быть ** список ключевых слов? ** Может быть, данные ** получены из базы данных? ** Возможно, вы просто хотите, чтобы это поле было уникальным? ** Если да, то почему вы прилагая усилия по скрытию ключевой информации о вашей проблеме? –