6

Say I have a MethodView looking like this:

from flask import jsonify, request, redirect, flash, views, url_for
from models import Provider

class ProviderAPI(views.MethodView):

    def get(self, provider_id):
        if provider_id is not None:
            provs = [Provider.objects.get_by_id(provider_id)]
        else:
            provs = Provider.objects.all()
        return jsonify(dict(objects=[x.attributes_dict for x in provs]))

    def post(self):
        data = request.form.to_dict()
        data['index'] = request.form.getlist('index')
        if data:
            obj = Provider(**data)
            if obj.is_valid():
                obj.save()

                flash('%s created' % obj, )

                return redirect(url_for(
                    'provider',
                    provider_id=obj.id,
                    )
                )
            else:
                return jsonify(obj.errors)

    def put(self, provider_id):
        pass

    def delete(self, provider_id):
        pass

This get registered with this known snippet:

def register_api(view, endpoint, url, pk='id', pk_type='int'):
    """
    Helper for the API boilerplate, `view` must inherit from MethodView 

    register_api(UserAPI, 'user', '/user/', pk='provider_id')
    """
    view_func = view.as_view(endpoint)

    app.add_url_rule(url, defaults={pk: None},
                     view_func=view_func, methods=['GET',])
    app.add_url_rule(url, view_func=view_func, methods=['POST',])
    app.add_url_rule('%s<%s:%s>' % (url, pk_type, pk), view_func=view_func,
                     methods=['GET', 'PUT', 'DELETE'])

The thing is, that after the post is successful it'm being redirected the get function but with a POST call and it raises Method Not Allowed.

127.0.0.1 - - [08/Aug/2012 12:35:21] "POST /provider/ HTTP/1.1" 302 -
127.0.0.1 - - [08/Aug/2012 12:35:21] "POST /provider/44 HTTP/1.0" 405 -

Is there a way to tell redirect to use a GET call instead?

tutuca
  • 3,444
  • 6
  • 32
  • 54
  • 2
    I'm getting this as well, but have no answer and stumbled on this question. Did you find an answer? – blueblank Oct 02 '12 at 19:43
  • No man. Went back to doing the project in django, although flask looks way better... – tutuca Oct 03 '12 at 20:56
  • 4
    302 volatility http://tools.ietf.org/html/rfc2616#section-10.3.3 "*Note: RFC 1945 and RFC 2068 specify that the client is not allowed to change the method on the redirected request. However, most existing user agent implementations treat 302 as if it were a 303 response, performing a GET on the Location field-value regardless of the original request method. The status codes 303 and 307 have been added for servers that wish to make unambiguously clear which kind of reaction is expected of the client.*" – soulseekah Dec 07 '12 at 05:41
  • 1
    You should post that as an answer, not as a comment. – LtWorf Mar 15 '13 at 10:33

1 Answers1

2

It looks like a 302 redirect can be made with the same request method as the previous request. A 303 redirect, however, should always use GET (source).

The redirect function can take a status code. Try this:

            return redirect(url_for(
                'provider',
                provider_id=obj.id,
                ),
                code=303
            )

Edit: Similar discussion: Redirecting to URL in Flask

Community
  • 1
  • 1
computmaxer
  • 1,677
  • 17
  • 28