docs: def _to_bytes(self, data, key='', expired=None, noc=0, ncalls=0):
          """Serialize (and encrypt if `key` is provided) the data and represent it as string.
  
          **Parameters**
  
              :param data: any python serializable (pickable) object
              :param key: If the key is provided and `pycrypto` is installed, cached
                          data will be encrypted (If `pycrypto` is not installed, this #TODO: pycrypto or something else?!
                          parameter will be ignored). Empty string by default.
              :param expired: exact date when the cache will be expired; It is `None` by default
              :param noc: the number of allowed calls; TODO: Clarify what does it mean, exactly?!!!!
              :param ncalls: What is it; I don't understand!!! TODO: clarify this!!!!
              :type key: str
              :type expired: `datetime` or `None`
              :type noc: int
              :type ncalls: int
              :returns: serialized data
              :rtype: str
          """
  
          data_tuple = (data, expired, noc, ncalls)
  
          if not can_encrypt and key:
              # TODO: Probably not only Pycrypto will be using for encryption!!!
              # Clarification needed
              warnings.warn("Pycrypto is not installed. The data will not be encrypted",
                            UserWarning)
              result = encode_safely(data_tuple)
          elif can_encrypt and key:
              if PY3:
                  cipher = AESCipher(key.encode(settings.DEFAULT_ENCODING))
              else:
                  cipher = AESCipher(key)
              result = cipher.encrypt(encode_safely(data_tuple))
          else:
              result = encode_safely(data_tuple)
          return result