Example #1
0
    def __init__(self, **kwargs):
        # make sure we have at least one required key
        valid_response = False
        for k in [ 'results', 'modal', 'toast', 'html' ]:
            if k in kwargs:
                valid_response = True
                break
        if not valid_response:
            raise Exception('AJAX mixed response requested but no recognized response types provided')

        # validate each of our possible sub-keys and
        # make sure they're JSON-able

        if 'modal' in kwargs:
            modal = kwargs['modal']
            if 'code' not in modal or 'message' not in modal:
                raise Exception('AJAX modal response requested but code and message values are required')
                
            # JSON-safe the acceptable bits
            attrs = [ 'code', 'title', 'message' ]
            if 'size' in modal and modal['size'] != None:
                # NOTE: we ignore size if it's None as it confuses the JavaScript
                attrs.append('size')
            kwargs['modal'] = to_json(modal, attrs)

        if 'toast' in kwargs:
            toast_list = kwargs['toast']
            if isinstance(toast_list, dict):
                toast_list = [ toast_list ]     # a single dict is permitted, wrap as list
            for toast in toast_list:
                if 'duration' not in toast or 'html' not in toast:
                    raise Exception('AJAX toast response requested but a toast is missing required duration or message values')
                    
            kwargs['toast'] = to_json(toast_list)
            
        if 'html' in kwargs:
            html_list = kwargs['html']
            for html in html_list:
                if 'id' not in html or 'html' not in html:
                    raise Exception('AJAX HTML update response requested but an update is missing required id or html values')
                    
            kwargs['html'] = to_json(html_list)

        # NOTE: we don't apply to_json() to any "results"
        # data, as we assume this is done by the calling
        # code in order to control object serialization

        # this value is a marker to the client-side code
        # that indicates it adheres to the correct JSON
        # response format
        kwargs['sculpt'] = 'ajax'

        super(AjaxMixedResponse, self).__init__(kwargs)
Example #2
0
 def __init__(self, response = None, **kwargs):
     if not response:
         response = to_json(kwargs, [ 'code', 'title', 'message' ])
         if 'size' in kwargs:
             response['size'] = kwargs['size']
     # this really should verify the required keys are present in the response
     # (code, title, message)
     super(AjaxErrorResponse, self).__init__({ 'sculpt': 'ajax', 'error' : response })
Example #3
0
    def __init__(self, form, last_field = None, focus_field = None, error = None):
        # check whether this is a partial validation response
        is_partial = last_field != None
        
        # we shouldn't do this unless we actually have form errors;
        # that would be a programming mistake
        # NOTE: we'll accept a partial-validation error-free state
        if not is_partial and not form._errors:
            raise Exception('attempt to return form errors when there are none')

        # we need to format the errors in the form in a way that
        # is suitable for our AJAX handler on the client
        #
        # NOTE: Django's method is that the ValidationError and
        # ErrorList classes should "know" how to format themselves,
        # but they left very little in the way of ability to
        # intelligently override that. Instead, we act as though
        # errors are collected into a well-defined format, and
        # the layer that returns these errors to the client is
        # responsible for correctly formatting them.

        # we walk the error list in field declaration order
        error_list = []
        for name, field in form.fields.iteritems():
            if name in form._errors:
                field_error_list = []
                for message in form._errors[name]:
                    field_error_list.append(force_text(message))
                # use prefixed name so client side can find it
                error_list.append([ form.add_prefix(name), field.label, field_error_list ])

        # now append the global errors
        name = '__all__'
        if name in form._errors:
            field_error_list = []
            for message in form._errors[name]:
                field_error_list.append(force_text(message))
            error_list.append([ None, None, field_error_list ])

        # now that we have a formatted error list, return it
        results = {
                'sculpt': 'ajax', 
                'form_error': error_list,
            }
        if is_partial:
            results['partial'] = {
                    'last_field': form.add_prefix(last_field),
                    'focus_field': form.add_prefix(focus_field),
                }
        if error != None:
            results['error'] = to_json(error, [ 'code', 'title', 'message' ])   # just these valid fields
            if 'size' in error:
                results['error']['size'] = error['size']

        super(AjaxFormErrorResponse, self).__init__(results)