Send a message to admin from the save method in a Displayable model

2,862 views
Skip to first unread message

Rainell Dilou Gómez

unread,
Oct 13, 2017, 4:36:13 PM10/13/17
to Mezzanine Users
Hello everyone,
I need send a message to admin from the save method in a model, something like that:

class MyModel(Displayable, Ownable, RichText):

   
# some field

   
def save(self, *args, **kwargs):

       
# do something

       
# set the message to be displayed

       
super(MyModel, self).save(*args, **kwargs)

Then, in the admin, the message should be displayed when the form is sent (save).

I have done a test after having read documentation, questions on stackoverflow.com, etc. The test doesn't generate errors during the execution but I don't get the result I want, the default Mezzanine message is still displayed, my custom message isn't displayed.
The code of my test would look like that:

from django.db import models
from django.utils.translation import ugettext_lazy as _
from mezzanine.core.models import Displayable, Ownable, RichText

from django.contrib import messages
from django.test import RequestFactory
from django.contrib.messages.storage.fallback import FallbackStorage

def create_request(url):
    factory
= RequestFactory()
    request
= factory.get(url)
    setattr
(request, 'session', 'session')
    messages
= FallbackStorage(request)
    setattr
(request, '_messages', messages)
   
return request

class MyModel(Displayable, Ownable, RichText):

   
# some field

   
def save(self, *args, **kwargs):

       
# do something

        url
= "/admin/path_to/the_instance/%s/change/" % self.id
        request
= create_request(url)
        messages
.error(request, _("My custom message."))

As I said earlier, this does not generate errors, but the message is not displayed.
Please, how can I do it?

Eduardo Rivas

unread,
Oct 13, 2017, 4:42:56 PM10/13/17
to mezzani...@googlegroups.com

I would recommend you move this logic to the admin view, where the request is going to be available at all times. Specifically, you should register your own admin class and override the save_model() method, as described here: https://docs.djangoproject.com/en/1.11/ref/contrib/admin/#django.contrib.admin.ModelAdmin.save_model. Don't forget to call super() to actually save the model instance before your custom logic!

Also, keep in mind ModelAdmin provides message_user() as a convenience to display messages in the admin. https://docs.djangoproject.com/en/1.11/ref/contrib/admin/#django.contrib.admin.ModelAdmin.message_user
--
You received this message because you are subscribed to the Google Groups "Mezzanine Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to mezzanine-use...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Rainell Dilou Gómez

unread,
Oct 13, 2017, 4:53:04 PM10/13/17
to Mezzanine Users
Thank you very much Eduardo, I'll try it as you recommend.

Rainell Dilou Gómez

unread,
Oct 14, 2017, 9:18:06 AM10/14/17
to Mezzanine Users
Hi Eduardo,
I have tried as you suggested, my new test would be something like this:

from django.contrib import messages
from django.utils.translation import ugettext_lazy as _
from mezzanine.core.admin import DisplayableAdmin, OwnableAdmin

class MyModelAdmin(DisplayableAdmin, OwnableAdmin):

   
# fieldsets, list_display, etc.

   
def save_model(self, request, obj, form, change):

       
# do something

       
return DisplayableAdmin.message_user(request, _("My custome message."), messages.ERROR)

but now I get the following error:

add_message() argument must be an HttpRequest object, not '__proxy__'.

to see what contains the request object, I have used raise Exception(request) and got

<WSGIRequest: POST '/admin/.../'>

Please, what could I do now?


Il giorno venerdì 13 ottobre 2017 22:36:13 UTC+2, Rainell Dilou Gómez ha scritto:

Rainell Dilou Gómez

unread,
Oct 14, 2017, 10:30:20 AM10/14/17
to Mezzanine Users
I have changed


return DisplayableAdmin.message_user(request, _("My custome message."), messages.WARNING

by

return self.message_user(request, _("My custome message."), messages.WARNING)

My custom message (WARNING) is now displayed, but also the predefined Mezzanine message (SUCCESS), both are displayed, as shown in the following image



Il giorno venerdì 13 ottobre 2017 22:36:13 UTC+2, Rainell Dilou Gómez ha scritto:

Eduardo Rivas

unread,
Oct 14, 2017, 10:23:29 PM10/14/17
to mezzani...@googlegroups.com

If that's the case you may want to override response_change() instead. This method is quite complex and determines which message to display depending on what action the user just triggered (save, save and continue, save and add new, etc). https://docs.djangoproject.com/en/1.11/_modules/django/contrib/admin/options/#ModelAdmin.response_change

--

Rainell Dilou Gómez

unread,
Oct 15, 2017, 5:40:29 AM10/15/17
to Mezzanine Users
Thanks again for your help Eduardo.
I have taken a look at the response_change method and I have done a test. This method isn't appropriate for my case because it isn't triggered when the change has made from the listing page. Change the status of the records (Draft/Published) will be the most frequent action in this model, and will be done mainly from the listing page. Then it's necessary that the method used is also triggered from the listing page.


Il giorno venerdì 13 ottobre 2017 22:36:13 UTC+2, Rainell Dilou Gómez ha scritto:
Reply all
Reply to author
Forward
0 new messages