code: def from_message(cls, message):
          
          self = cls(json=message)
          try:
              decoded_data = json.loads(message)
          except ValueError:
              # Message is not a valid JSON. Return as invalid.
              return self
          try:
              report_data = decoded_data['csp-report']
          except KeyError:
              # Message is not a valid CSP report. Return as invalid.
              return self
  
          # Extract individual fields
          for report_name, field_name in REQUIRED_FIELD_MAP + OPTIONAL_FIELD_MAP:
              setattr(self, field_name, report_data.get(report_name))
          # Extract integer fields
          for report_name, field_name in INTEGER_FIELD_MAP:
              value = report_data.get(report_name)
              field = self._meta.get_field(field_name)
              min_value, max_value = connection.ops.integer_field_range(field.get_internal_type())
              if min_value is None:
                  min_value = 0
              # All these fields are possitive. Value can't be negative.
              min_value = max(min_value, 0)
              if value is not None and min_value <= value and (max_value is None or value <= max_value):
                  setattr(self, field_name, value)
          # Extract disposition
          disposition = report_data.get('disposition')
          if disposition in dict(DISPOSITIONS).keys():
              self.disposition = disposition
  
          # Check if report is valid
          is_valid = True
          for field_name in dict(REQUIRED_FIELD_MAP).values():
              if getattr(self, field_name) is None:
                  is_valid = False
                  break
          self.is_valid = is_valid
  
          return self
docs: Creates an instance from CSP report message.
  
          If the message is not valid, the result will still have as much fields set as possible.
  
          @param message: JSON encoded CSP report.
          @type message: text