Opened 19 years ago

Closed 19 years ago

Last modified 18 years ago

#828 closed defect (worksforme)

Same function used for GET and POST

Reported by: aaronsw Owned by: Adrian Holovaty
Component: Database layer (models, ORM) Version:
Severity: normal Keywords:
Cc: Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

Django encourages the use of the same function for both GET and POST (not to mention DELETE) methods. For example, 'module.method' resolves to:

def method(request): ...

In the web app framework I wrote, it resolves to:

class method:
    def GET(self, request): ...
    def POST(self, request): ...
    ...

This ensures that POST functions don't accidentally leak into GETs. If both POST and GET want to reuse code, then they can add a new method to the class. This also allows this style:

...
(r'^/method/(.*)', 'module.method')
...

class method:
    GET = web.autodelegate("GET_")
    POST = web.autodelegate("POST_")
    
    def GET_(self, request): ... # index
    def GET_pagename(self, request): ...
    def POST_pagename(self, request): ...

which makes adding new URLs easy. The code for autodelegate is simply:

def autodelegate(prefix=''):
    def internal(self, request, arg):
        func = prefix+arg
        if hasattr(self, func): return getattr(self, func)(request)
        else: raise NotFound
    return internal

Change History (6)

comment:1 by Jacob, 19 years ago

FYI, there are decorators in django.views.decorators.http to control which request methods a given view allows; this is a very interesting idea, though.

comment:2 by brantley (deadwisdom@…, 19 years ago

This is an interesting idea. But you could still do this sort of thing, actually without changes in django. If you had your method class define call(), like so:

class MethodPage:
   def __call__(request, **kw):
      if request.GET:
          self.get(request, **kw)
      elif request.POST:
          self.post(request, **kw)
      else:
          self.default(request, **kw)

   def get(request, **kw):
      pass
   def post(request, **kw):
      pass
   def default(request, **kw):
      pass

And then use it in your page:

class method(MethodPage):
    def get(request, arg1, arg2):
        "Does stuff on get."
    def post(request, arg1, arg2):
        "Does stuff on post."

comment:3 by anonymous, 19 years ago

Oh, and finally, make it a singleton:

    method = method()

comment:4 by hugo, 19 years ago

Actually your code only works if you make get/post/whatever classmethods, as otherwise they will require a MethodPage object in the first parameter ;)

comment:5 by Adrian Holovaty, 19 years ago

Resolution: worksforme
Status: newclosed

See the comments on this ticket.

comment:6 by Adrian Holovaty, 18 years ago

milestone: Version 0.91

Milestone Version 0.91 deleted

Note: See TracTickets for help on using tickets.
Back to Top