kurtgn
kurtgn

Reputation: 8710

cancel saving model in django admin save_model()

I overrode django-admin's save_model for some model, so that in some cases the model is not saved.

def save_model(self, request, obj, form, change):
    """При сохранении списка проверить на совпадения.

    - Не должно быть двух CTR 0 списков для одной страы
    - Не должно быть двух CTR low списков для одной страны,
            подхода, ограничения по трафику, пользователя и рекламной сети.
    """
    cls = obj.__class__
    if obj.type == ListTypes.ctr0.value:
        existing_lists = (cls.objects
                          .filter(country=obj.country,
                                  user=obj.user,
                                  type=obj.type)
                          .exclude(pk=obj.pk)
                          .all())
        if existing_lists:
            msg = 'Список CTR 0 для страны {} уже существует.'
            msg = msg.format(obj.country)
            self.message_user(request, _(msg), level=messages.ERROR)
            return
        if obj.angle or obj.traffic_restriction:
            msg = ('Для списков CTR 0 нельзя задавать подходы '
                   'и ограничения по трафику.')
            self.message_user(request, _(msg), level=messages.ERROR)
            return
        obj.save()

When the object is edited and conditions for not saving are met, then it is not saved, error message is flashed, everything is alright.

However, when a new object is added and conditions for not saving are met, the object is not saved again, but django crashes.

The crash looks like this

TypeError at /admin/pubscout/list/add/
coercing to Unicode: need string or buffer, NoneType found

The point of crash is here, in the native django logger code:

            if add:
                self.log_addition(request, new_object, change_message)
                return self.response_add(request, new_object)
            else:
                self.log_change(request, new_object, change_message)
                return self.response_change(request, new_object)

basically, it tries to log the action of saving the object, but the object is not present, so new_object is None, and logger crashes.

How to avoid this? Is there a way to conditionally disable logging or whatever?

Upvotes: 1

Views: 2967

Answers (1)

bryanph
bryanph

Reputation: 1012

It is correct that the save_model method must save the instance. It is not meant for validation of any kind. For that purpose, you can create a custom Form that implements validation through the "clean" methods.

Take a look at https://docs.djangoproject.com/en/1.9/ref/contrib/admin/#adding-custom-validation-to-the-admin

Upvotes: 1

Related Questions