parameters: (request, parse_row_function, add_new_function, formdict, cache={})
return_statement: return response
docstring: Bulk adds data by parsing an input 2D array serially adding each row.
  
      Args:
          request: The Django context which contains information about the
              session and the 2D data array for the handsontable bulk add request
          parse_row_function: A callback function that will handle parsing
              of each row's fields and values and then return the Django
              form representation.
          add_new_function: A callback function that will handle bulk adding
              a single row.
          formdict: The dictionary representation of the form
  
      Returns:
          Returns an array of dictionaries from the input form. Includes the
          following keys in the dictionary:
  
              failedRows: An array with a dictionary of key/value pairs with
                  information about which rows and why the failure occurred.
                  The following are the dictionary keys:
  
                      row: The row of the failure
                      col: The column of the failure. If the value is -1
                          then that means the column where the error occurred
                          is not determined.
                      label: The label of the column, if available
                      message: The reason for the failure
  
              messages: Helpful messages about the bulk add operations
              success: A boolean indicating if the bulk add operations were successful
              successfulRows: An array with a dictionary of key/value pairs with
                  information about which rows were successfully bulk added.
                  The following are the dictionary keys:
  
                      row: The row that was successful
              secondary: An array of information that can be passed from the
                  add_new_function() function call back to the caller of this
                  function. There are no restrictions on the data that can be
                  passed back. Usually this is used for post processing
                  analysis of the entire bulk add operation as a whole.
docstring_summary: Bulk adds data by parsing an input 2D array serially adding each row.
docstring_tokens: Bulk adds data by parsing an input 2D array serially adding each row .
function: def parse_bulk_upload(request, parse_row_function, add_new_function, formdict, cache={}):
      """Bulk adds data by parsing an input 2D array serially adding each row.
  
      Args:
          request: The Django context which contains information about the
              session and the 2D data array for the handsontable bulk add request
          parse_row_function: A callback function that will handle parsing
              of each row's fields and values and then return the Django
              form representation.
          add_new_function: A callback function that will handle bulk adding
              a single row.
          formdict: The dictionary representation of the form
  
      Returns:
          Returns an array of dictionaries from the input form. Includes the
          following keys in the dictionary:
  
              failedRows: An array with a dictionary of key/value pairs with
                  information about which rows and why the failure occurred.
                  The following are the dictionary keys:
  
                      row: The row of the failure
                      col: The column of the failure. If the value is -1
                          then that means the column where the error occurred
                          is not determined.
                      label: The label of the column, if available
                      message: The reason for the failure
  
              messages: Helpful messages about the bulk add operations
              success: A boolean indicating if the bulk add operations were successful
              successfulRows: An array with a dictionary of key/value pairs with
                  information about which rows were successfully bulk added.
                  The following are the dictionary keys:
  
                      row: The row that was successful
              secondary: An array of information that can be passed from the
                  add_new_function() function call back to the caller of this
                  function. There are no restrictions on the data that can be
                  passed back. Usually this is used for post processing
                  analysis of the entire bulk add operation as a whole.
      """
  
      failedRows = []
      successfulRows = []
      messages = []
      secondaryData = []
      isFailureDetected = False
      is_validate_only = convert_string_to_bool(request.POST['isValidateOnly'])
      offset = int(request.POST.get('offset', 0));
  
      if cache.get("cleaned_rows_data"):
          cleanedRowsData = cache.get("cleaned_rows_data");
      else:
          cleanedRowsData = convert_handsontable_to_rows(request);
  
      rowCounter = offset;
      processedRows = 0;
  
      for rowData in cleanedRowsData:
          rowCounter = rowCounter + 1
  
          # Make sure that the rowData has content, otherwise the client side
          # might have done some filtering to ignore rows that have no data.
          if(rowData == None):
              continue;
  
          try:
              bound_form = parse_row_function(request, rowData, cache)
  
              # If bound form passes validation checks then continue adding the item
              if bound_form.is_valid():
                  data = bound_form.cleaned_data
                  errors = []
                  retVal = {}
                  message = ""
  
                  (result, errors, retVal) = add_new_function(data, rowData, request, errors, is_validate_only, cache)
  
                  processedRows += 1;
  
                  #if retVal.get('message'):
                  #    messages.append("At row " + str(rowCounter) + ": " + retVal.get('message'))
                  if retVal.get('secondary'):
                      secondaryData.append(retVal.get('secondary'))
  
                  # Check to make sure there were no errors
                  for error in errors:
                      message += error + '; '
                  else:
                      message = message[0:-2] # Remove '; ' from last
  
                  if errors:
                      # If there was an error then use a "col" value of -1, this is needed because
                      # there is no easy way to indicate the specific column that caused the error.
                      # The "col": -1 will just indicate to the client side to highlight the entire row.
                      failedRows.append({'row': rowCounter,
                                         'col': -1,
                                         'message': "At row " + str(rowCounter) + ": " + message});
                  else:
                      status = retVal.get(form_consts.Status.STATUS_FIELD, form_consts.Status.SUCCESS);
                      data = {'row': rowCounter, 's': status};
  
                      if retVal.get('warning'):
                          data['message'] = "At row " + str(rowCounter) + ": " + retVal.get('warning');
                      elif retVal.get('message'):
                          data['message'] = "At row " + str(rowCounter) + ": " + retVal.get('message');
  
                      successfulRows.append(data);
  
              # ... otherwise validation of the bound form failed and we need to
              # populate the response with error information
              else:
                  processedRows += 1;
  
                  for name, errorMessages in bound_form.errors.items():
                      entry = get_field_from_label(name, formdict)
                      if entry == None:
                          continue
                      for message in errorMessages:
                          failedRows.append({'row': rowCounter,
                                             'col': entry['position'],
                                             'label': entry['label'],
                                             'message': "At (" + str(rowCounter) + ", " + entry['label'] + "): " + message});
  
          except Exception,e:
              import traceback
              traceback.print_exc()
  
      # Populate the response to send back to the client
      response = {}
      response['success'] = (not isFailureDetected)
      response['messages'] = messages
      response['failedRows'] = failedRows
      response['successfulRows'] = successfulRows
      response['secondary'] = secondaryData
      response['processed'] = processedRows
  
      return response
function_tokens: def parse_bulk_upload ( request , parse_row_function , add_new_function , formdict , cache = { } ) : failedRows = [ ] successfulRows = [ ] messages = [ ] secondaryData = [ ] isFailureDetected = False is_validate_only = convert_string_to_bool ( request . POST [ 'isValidateOnly' ] ) offset = int ( request . POST . get ( 'offset' , 0 ) ) if cache . get ( "cleaned_rows_data" ) : cleanedRowsData = cache . get ( "cleaned_rows_data" ) else : cleanedRowsData = convert_handsontable_to_rows ( request ) rowCounter = offset processedRows = 0 for rowData in cleanedRowsData : rowCounter = rowCounter + 1 # Make sure that the rowData has content, otherwise the client side # might have done some filtering to ignore rows that have no data. if ( rowData == None ) : continue try : bound_form = parse_row_function ( request , rowData , cache ) # If bound form passes validation checks then continue adding the item if bound_form . is_valid ( ) : data = bound_form . cleaned_data errors = [ ] retVal = { } message = "" ( result , errors , retVal ) = add_new_function ( data , rowData , request , errors , is_validate_only , cache ) processedRows += 1 #if retVal.get('message'): #    messages.append("At row " + str(rowCounter) + ": " + retVal.get('message')) if retVal . get ( 'secondary' ) : secondaryData . append ( retVal . get ( 'secondary' ) ) # Check to make sure there were no errors for error in errors : message += error + '; ' else : message = message [ 0 : - 2 ] # Remove '; ' from last if errors : # If there was an error then use a "col" value of -1, this is needed because # there is no easy way to indicate the specific column that caused the error. # The "col": -1 will just indicate to the client side to highlight the entire row. failedRows . append ( { 'row' : rowCounter , 'col' : - 1 , 'message' : "At row " + str ( rowCounter ) + ": " + message } ) else : status = retVal . get ( form_consts . Status . STATUS_FIELD , form_consts . Status . SUCCESS ) data = { 'row' : rowCounter , 's' : status } if retVal . get ( 'warning' ) : data [ 'message' ] = "At row " + str ( rowCounter ) + ": " + retVal . get ( 'warning' ) elif retVal . get ( 'message' ) : data [ 'message' ] = "At row " + str ( rowCounter ) + ": " + retVal . get ( 'message' ) successfulRows . append ( data ) # ... otherwise validation of the bound form failed and we need to # populate the response with error information else : processedRows += 1 for name , errorMessages in bound_form . errors . items ( ) : entry = get_field_from_label ( name , formdict ) if entry == None : continue for message in errorMessages : failedRows . append ( { 'row' : rowCounter , 'col' : entry [ 'position' ] , 'label' : entry [ 'label' ] , 'message' : "At (" + str ( rowCounter ) + ", " + entry [ 'label' ] + "): " + message } ) except Exception , e : import traceback traceback . print_exc ( ) # Populate the response to send back to the client response = { } response [ 'success' ] = ( not isFailureDetected ) response [ 'messages' ] = messages response [ 'failedRows' ] = failedRows response [ 'successfulRows' ] = successfulRows response [ 'secondary' ] = secondaryData response [ 'processed' ] = processedRows return response