Search code examples
djangojquerydjango-piston

django-piston method is not allowed


I have this:

handlers.py

class ChatHandler(BaseHandler):
    model = ChatMsg
    allowed_methods = ('POST','GET')

    def create(self, request, text):
        message = ChatMsg(user = request.user, text = request.POST['text'])
        message.save()
        return message

template.html

    ...
    <script type="text/javascript">
    $(function(){
        $('.chat-btn').click(function(){
            $.ajax({
                url: '/api/post/',
                type: 'POST',
                dataType: 'application/json',
                data: {text: $('.chat').val()}
            })
        })
    })
    </script>
    ...

api/urls.py

chat_handler = Resource(ChatHandler, authentication=HttpBasicAuthentication)
urlpatterns = patterns('',
    ....
    url(r'^chat/$', chat_handler, {'emitter_format': 'json'}),
)

Why, but POST method is allowed in ChatHandler? GET method is working. Is it bug, or my code is wrong?


Solution

  • Even though you didn't include this code in your question, I found it in your github you gave in comments...

    You are mapping to a handler that does not allow POST requests

    urls.py ::snip::

    post_handler = Resource(PostHandler, authentication=auth)
    chat_handler = Resource(ChatHandler, authentication=auth)
    urlpatterns = patterns('',
        url(r'^post/$', post_handler , { 'emitter_format': 'json' }),
        url(r'^chat/$', chat_handler, {'emitter_format': 'json'}),
    )
    

    handlers.py

    # url: '/api/post'
    # This has no `create` method and you are not 
    # allowing POST methods, so it will fail if you make a POST
    # request to this url
    class PostHandler(BaseHandler):
        class Meta:
            model = Post
    
        # refuses POST requests to '/api/post'
        allowed_methods = ('GET',)
    
    
        def read(self, request):
            ...
    
    # ur;: '/api/chat'
    # This handler does have both a POST and GET method allowed.
    # But your javascript is not sending a request here at all.
    class ChatHandler(BaseHandler):
        class Meta:
            model = ChatMsg
        allowed_methods = ('POST', 'GET')
    
        def create(self, request, text):
            ...
    
        def read(self, request):
            ...
    

    Your javascript requests is being sent to '/api/post/', which is being routed to the PostHandler. I get the sense that you expected it to go to the chat handler. That means you need to change the javascript request url to '/api/chat/', or move the code to the handler you expected.

    Also, you are setting the model wrong in the handlers. It does not need a Meta nested class. It should be:

    class PostHandler(BaseHandler):
        model = Post
    
    class ChatHandler(BaseHandler):
        model = ChatMsg