Repository navigation
Processing POST request in several Content Types #604
Description
Activity
The problem is that you are returning something from process(). This will short-circuit the evaluation of further content types and use the HttpResponseRedirect returned as the overall return value of the page. FeinCMS assumes that if a content type returns a HttpResponseSomething, it has a deeper reason for doing that and the rest of the page won't be rendered anyway, so it won't process any further content types.
That means the easiest way to make both content types work is not to return something from process().
Perhaps we should process() all CTs anyway? Opinions?
The problem is that you are returning something from process(). This will short-circuit the evaluation of further content types and use the HttpResponseRedirect returned as the overall return value of the page. FeinCMS assumes that if a content type returns a HttpResponseSomething
Not exactly. Yes, you can short-circuit evaluation if you return HttpResponseSomething from your CT, but you can return True, letting other content types to be processed normally. I noticed that this is what occurs in case of GET, and so investigated a bit further why I am getting problems with POST. Look for the link to mixins module below.
Perhaps we should process() all CTs anyway? Opinions?
It seems that all content types are actually processed:
feincms.module.mixinsI realized that the origin of my issue lied in a completely different place. The thing is, I also put an ApplicationContent above both of these forms. 3rd party apps require urlpatterns defined, and the docs use class-based view (
ListView) in the app urls.When 3rd party app is defined this way, it actually tries to accept post requests, but fails to do so - the code in mixins module raises
django.http.response.HttpResponseNotAllowed, preventing other content types from processing POST request (since http responses short circuit the execution, as you mentioned)My solution to this particular problem was simple - I made a child class of ListView with an empty
post()method, like so:class CustomizedListView(ListView): # ... your code here def post(self, request, **kwargs): return TrueThis prevents ApplicationContent instances from raising
HttpResponseNotAllowedon POST requests: they return True instead, and let your process it in the other content types present on your page.
Now, back to the forms: yes, you can easily solve this problem if you assign a unique
nameattribute for submit buttons per each type of your CT Form:<button type="submit" name="ct_form_type" value="Submit" id="form_id" class="btn btn-success"> Submit </button>Then the
process()method of each content type form should be implemented like so:def process(self, request, **kwargs): if request.method == 'POST': if not 'ct_form_type' in request.POST: return True # ...In other words, we check that we stumbled across the right handler before processing the form itself. If this is the wrong handler, we return True, giving other content types a chance to process POST. If neither of content types handles POST, 405 status code is returned.
I am trying to put two different forms on a single page. These forms are implemented in the same manner as the bundled ContactFormContent. Basically, they have a form class and a model class, where the model class has process() method that handles requests.
If I add one of these forms to the page, everything works fine: when user submits the form, process() handles the POST request, and performs all the necessary logic. However, if both of these forms are present on the same page, the second form will be processed in the
process()method of the first one.This seems to be logically correct: since templates of the both forms contain
method="post" action=".", the submitted form is processed by the first handler found on the same page. However, if I comment out the entireprocess()method of the first form, the second form processes GET requests only, and completely ignores POST requests for some reasons. As the result, django returns status code 405 when I submit the second form, just as if POST handler was not defined at all.I found the code that runs
process()in each content type at module/mixins.py. I tried analyzing request data to check which form was submitted, and, if it was the wrong form, returning True inprocess(), to give another form a chance to run itsprocess()afterwards, but that didn't help.What may be the issue here? Is it possible to put different forms, defined as two different content types, on the same page in feincms? What is the correct way to handle POST requests in different content types present on the same page?