Django: How to change to success message for update_object? - django

I'm using the django messages framework for user notifications and update_object to handle saving of forms. When a form is successfully posted the default message is [MyModel] successfully saved or similar.
I want to change this message to a custom one ("Your changes were saved"), either for all form posts or for every use of update_object.
Is this possible?
Thanks!

I am assuming that you are talking about the update_object generic view.
If that is the case then there is no way (hook) to change the success message at present (Django 1.2.3). You can see this for yourself in the source code. Just look for update_object.
One rather flaky way to do this would be to use a custom post_save_redirect and render the message yourself. The post_save_redirect can be a simple view to display the appropriate success message. This will mean losing the redirection to the object's permalink though.
You can also try adding a custom message (using messages.success) and then redirect to the saved object's permalink in the wrapper. I haven't tried this myself so I do not know how this will turn out.

Related

Rails: Template is missing / one method for handling POST and GET requests?

I am a Rails newb, and am simply trying to flash an error, on a view with a form. When I sent a POST request to the path of the view I would like to flash the error on, my routes.rb file sends the POST request to my update method in my SchoolApplicationsController. However update is viewless so when I make the POST request to go there, and I meet an error case, I get Template is missing from my Rails Server.
The view where I would like to flash the error is the view which made the request to POST called the pay method in the same controller. What is the common practice here? Do I route the POST for the form submission to the same method as I would do the GET for the pay view, so that any flash errors can be presented in the desired place?
To render a view in a "viewless" action you need to use the render method. In your case render :pay. It will render the form, already filling all the fields, filled previously (if you match the instance variables right).
To flash errors in that form you may use one of several options. First is to simply use flash.now['error'] = 'Whatever error message you need' before you do the rendering. Second is using the .errors method in the instance variable you are updating from the form. Look up the docs or use the console to look up what data that method provides.

Django admin, Proper way to create change_form that don't really save objects

Let's say I have a model Message. In admin, I need to add a message by submitting/uploading a message file, not by posting message fields as normally would. The process is, I get the file uploaded, send it to a processing program which parse the file, do some further processing and then add an entry into database.
So I create a custom form for ModelAdmin(assign form = CustomForm) with one FileField and override save_model() to not to save anything. However, this isn't a proper way as the doc clearly mention ModelAdmin's save_model() method is not for veto purpose. So what would be the proper way for this?
Some suggest an extra button pointed to a custom view, while it's surelly possible but logically I'm still adding a message so an extra view doesn't seem nature.

Django add contrib.messages from custom middleware

I have implemented a custom middleware that check for certain fields in a user's profile. The fields are not required at sign up (in order to make it quick and easy for a user to sign up), however, I would prefer that they fill them out.
My middleware checks if they are set. If not, it notifies the user via a message. I ran into two problems.
Whenever I submit a posted form, because no template displays the messages, the middleware would add the message a second time since the middleware was called when the message was posted and after the redirect it was called again.
I solved this problem by iterating through the messages in my middleware and checking if the message I am about to add is already in there. If yes, it doesn't add it again.
When a user fixes the problem by updating their profile, on the very next page load, the messages are still there. After that though, everything works. At the beginning of my middleware, I actually put a check that returns None if the request was posted (I would have thought this would solve both problems, but it didn't solve either).
Any idea how to solve the 2nd issue? Is there a better way to solve my first one?
Thanks.
Edit:
Is there a way to clear the messages in a view? I've tried iterating through them (without storage.used=False) and they are still there. I would expect that this would solve both my problems.
Yoy can use sticky messages of https://github.com/AliLozano/django-messages-extends that is one storage that only keeps messages in request instead save in session
So, are you using django.contrib.messages to store permanent notices? It's intended for showing one-time notifications, where the user sees the message once and then it goes away. The type of things it's meant for are messages like, "Form edited successfully."
As far as getting rid of messages in a user's message stack are concerned: any time you use a RequestContext (discussed here) to render a template, all messages will be flushed (whether they are actually shown on the page or not).
I'm not totally sure this is the answer you're actually after, and I'm a bit confused by your question. However, I'm somewhat sure you're using messages outside its intended purpose, which is likely why you're running into trouble.
You could use process_reponse() method of Middleware to add the message. By that time, you would know whether to show the message to user or not depending on whether his profile now has the field filled in.
Consider using django.contrib.messages. May be you do not want to show "fill in the XYZ field" message on all requests, but only on few pages, say whenever user logs in or views his profile page.
Just place logic that creates messages to context processor instead of middleware. Modify request and return empty dict.

where do functions that don't display go in django

I have some links on an html page like , , currently I handle them as so
<p> rate down
and have a url.py entry:
(r'^cases/(?P<case_id>\d+)/case_rate/(?P<oper>.)$', 'mysite.cases.views.case_rate'),
then I have a view function that handles the logic and hits the DB, then does this:
return HttpResponseRedirect(request.META.get('HTTP_REFERER','/'))
I's there a better way to do this? I can see how this would be OK because it does have to redraw the screen to show the new rating...
The typical way to handle this is with an ajax request.
Instead of a link, you put a javascript handler that calls a view, wich updates the db, and returns a json / xml object with the new rating for the item. Then another javascript handle receives that response and updates the rating number on the screen, without a page reload.
Ideally, you'll keep both versions: plain html (the one you currently have) and the ajax one. The ajax one can be attach to the element after page load, so if javascript is not available, you'll still have a working site.
Then, regarding organization, you can have an "ajax" parameter on your view. The view should update the db accordingly, and if it's an ajax call, return the json / xml response, otherwise, return the new page. That way you can keep the logic (fetching the object, updating the db) on one place.
If you're asking whether case_rate should still go in the views.py given that it returns a redirect rather than providing content, the answer is yes, since case_rate is handling an request and returning a response.
But consider a situation where you had two view functions in views.py that had some duplicate code, and you chose to factor that duplicate code into another function that didn't both take request and return a response. Would that be fair game to leave in views.py? Sure, if moving it elsewhere would make the code harder to read. Or you might choose to put it elsewhere. It's really your call based on your sense of taste.

django - returning form errors from a generic application view

I am developing a generic application. Let's assume that it handles Foo objects which can be attached to any model.
In a template, a Foo form can be shown by the get_foo_form template tag:
{% get_foo_form for object as form %}
object is the object which foo will be attached to.
The form posts to a view in the foos application. if the form is valid, everything is fine. the new foo is saved and the view redirects to the former page (via a 'next' argument hidden in the form) and the new foo is displayed nicely.
But if the form is not valid, I'm lost. For the same case, a similar application, the django.contrib.comments has an intermediary page that asks the user to correct the errors. However, I don't want to display an intermediary page, I want to show the former page with the errors. A redirection does not suffice here as I need to pass the error message(s) to the former page.
Is there a way to accomplish what I'm trying to do, or should I change the whole structure?
All you really need to do is to add the error messages to your dictionary when going back to the page you were at. Then in your HTML, add if tags to check if there are errors and display the appropriate errors if need be.
You could store your error messages in a list and then have that as one of the dictionary parameters in a call to render_to_response.
If you have an app featuring a generic model, the best way to pass error messages to the posting view after validating the form in the post handling view seems to be using the session to store the messages and redirecting back.
Thanks and +1 to AlbertoPL for his help.