tags:

views:

387

answers:

2

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?

+1  A: 

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.

AlbertoPL
@AlbertoPL The post_foo view gets the post request and checks if the form is valid. if it is valid, saves foo and redirects back to the view that shows the records. If it is not valid, I need to pass the error variables. I can't use httpresponseredirect because I can't pass any variables using it. render_to_response can't be used either, since the post view does not know or care about what the other view (that shows the records in the main application) does.
shanyu
oh ok, in that case, could you add a function in your other view that the post view can call to pass on the error messages? Then it would be up to that view to render the page with those error messages.
AlbertoPL
I'd really appreciate if you can provide me an example of what you mean, I'm not sure I get what you mean :)
shanyu
I'm under the assumption that you have different view files. Where you say views, do you mean templates? Because what I mean is that one view can import another and you can make a direct function call.
AlbertoPL
I'm talking about 2 views here, the one handling posts in the generic foo app, the one showing records in the main app. Here's what I was thinking before your reply: view, args, kwargs = resolve(next); kwargs['form_errors']=form._errors; return view(request, *args, **kwargs) but I didn't find this solution elegant. As far as I understand, you're suggesting something similar?
shanyu
I'm suggesting essentially the same thing. I think it's a perfectly good solution. It's actually the way Struts handles error messages and the only way I see of doing it without letting the views know more about each other.
AlbertoPL
AlbertoPL, thanks for your time. Two issues bug me. Pls correct me if I'm wrong. First, when a view calls another view, the url doesn't get updated, so I have a page showing records that displays a URL like 'example.com/foos/post'. Second, the generic post handling view, being generic, does not know how to properly call the other view (signature of the called view is not known to the caller), it just passes request and other variables. So it is not guaranteed that the call will be successful.
shanyu
These are definitely issues yes. You would have to make some sort of guarantee when making a call to another view. You could pass the URL you wanted to render in kwargs as well if you needed the URL to be different. Again, these are decisions you'd have to make.
AlbertoPL
I'd like to add that it is the separation of what renders the form and what checks the validity of the form that is the issue here. Is it not possible to have what renders the form also be the validator of that particular form? Or are you attempting to abstract that away as well?
AlbertoPL
Actually, I follow what django.contrib.comments does. My generic app provides a form (via a template tag), and views to handle post, delete and other requests. A view in the main app shows records and the form to post a new entry. The difference is that when the form is invalid, the comments app shows an intermediary page and asks for correction, and I try to redirect to the former page to show the form and error messages. What you suggest seems to require at the first glance to scrap this structure and build a new app that needs not to be so generic.
shanyu
I suspect they show the intermediary page because of exactly this problem :/Now that I think about it, you could store all of the error messages into the session and then retrieve them from the other view. Again, you'd have to have a single list with all of the messages, and you could have your template check for messages within that list.
AlbertoPL
Using the session has also come to my mind. Another possible solution: view,args,kwargs = resolve(next); kwargs['errors'] = form._errors; return httpresponseredirect (reverse (next, args=args, kwargs=kwargs). Here the show-records view needs an additional url (that incorporates errors) in urls.py. Everything aside, I really wonder how a better design can be developed.
shanyu
A: 

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.

shanyu