views:

246

answers:

2

I'm doing some stuff on 'clean' on an admin ModelForm:

class MyAdminForm(forms.ModelForm):
    def clean(self):
        # Some stuff happens...
        request.user.message_set.create(message="Some stuff happened")

class MyAdmin(admin.ModelAdmin):
    form = MyAdminForm

Other than the threadlocals hack - how do I access request.user to set a message? I can't pass it to the form constructor because doesn't get called from my code.

A: 

You would have to explicitly pass it there in constructor, which isn't a thing, that is usually done.

Are you sure you want to put that stuff into a form? What exactly you would like to do there? Isn't raising ValidationError enough?

gruszczy
As mentioned the Constructor isn't in my code - it's in contrib.admin.The message I want send isn't an error. It's a notification when saving the form has affected another part of the system.
andybak
But this is strange - how can you be sure, that you should send the message before actually saving the the object from the form? There might happen many different things between clean and save.
gruszczy
Bearing in mind we are talking about the admin change view what is likely to happen between clean and save?
andybak
Other clean may raise a ValidationError.
gruszczy
+2  A: 

You can't do it on the form without passing the user into the form constructor. Instead you can use the ModelAdmin.save_model function which is given the request object.

The save_model method is given the HttpRequest, a model instance, a ModelForm instance and a boolean value based on whether it is adding or changing the object. Here you can do any pre- or post-save operations.

http://docs.djangoproject.com/en/dev/ref/contrib/admin/#django.contrib.admin.ModelAdmin.save_model

Edit: Since you want to put the logic/messages in the clean function you could do something like:

class MyAdminForm(forms.ModelForm):
    user_messages = []
    def clean(self):
        # Some stuff happens...
        user_messages.append("Some stuff happened")

class MyAdmin(admin.ModelAdmin):
    form = MyAdminForm
    def save_model(self, request, obj, form, change):
        for message in form.user_messages:
            request.user.message_set.create(message=message)

Warning: This code has not been tested.

Mark Lavin
Mmmmm. The message depends on some validation logic so make much more sense living in the ModelForm clean() method. If I move it to ModelAdmin save_model() I'm going to have to write some messy logic just for the sake of sending a message!
andybak
Fair point. Check my edit and see if that helped.
Mark Lavin
I moved user_messages into the form's init and added self. to the 'user_messages.append' line and that worked a treat! Thanks.
andybak