1

my deorator function...

def validate_captcha(view):
    '''Decorator to validate a captcha based on settings'''

    def failure():
        return HttpResponse('You need to complete the captcha, please refresh and try again')

    if request.method == 'POST':

        url = "https://www.google.com/recaptcha/api/siteverify"
        values = {
            'secret': settings.GOOGLE_RECAPTCHA_SECRET_KEY,
            'response': request.POST.get(u'g-recaptcha-response', None),
            'remoteip': request.META.get("REMOTE_ADDR", None),
        }

        data = urllib.urlencode(values)
        req = urllib2.Request(url, data)
        response = urllib2.urlopen(req)
        result = json.loads(response.read())

        # result["success"] will be True on a success
        if result["success"]:
            return view
        else:
            return fail
    return fail

and then my view...

@validate_captcha
def sendemail(request):
    ...

I could put the request in the decorator args, but then it is undefined when i put it in the view args. I tried calling it a few others ways without success, how would you put it in there?

Joff
  • 11,247
  • 16
  • 60
  • 103

1 Answers1

3

You need to have a wrapper function:

def validate_captcha(view):
    def wrap(request, *args, **kwargs):
        if request.method == 'POST':

            url = "https://www.google.com/recaptcha/api/siteverify"
            values = {
                'secret': settings.GOOGLE_RECAPTCHA_SECRET_KEY,
                'response': request.POST.get(u'g-recaptcha-response', None),
                'remoteip': request.META.get("REMOTE_ADDR", None),
            }

            data = urllib.urlencode(values)
            req = urllib2.Request(url, data)
            response = urllib2.urlopen(req)
            result = json.loads(response.read())

            # result["success"] will be True on a success
            if result["success"]:
                return view
            else:
                return fail
        return fail
    return wrap

Make sure study this awesome and quite detailed overview on decorators in Python (I personally think, it is one of the best SO answers ever):

Community
  • 1
  • 1
alecxe
  • 462,703
  • 120
  • 1,088
  • 1,195
  • Thanks for this. I got all up in my head about "Oh I don't know Django" so I couldn't think in Python anymore! :) – Adam Smith Jan 29 '16 at 04:36
  • 1
    @AdamSmith exactly, Python comes built into Django :) – alecxe Jan 29 '16 at 04:38
  • @alecxe your suggestion worked, thanks, but I am getting another error now that is confusing me...haha...http://stackoverflow.com/questions/35077276/attribute-error-when-writing-a-captcha-decorator – Joff Jan 29 '16 at 05:05
  • @alecxe that's actually a really useful feature of Django :) – Adam Smith Jan 29 '16 at 06:35