2
0

exceptions.py 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. """
  2. Global Django exception and warning classes.
  3. """
  4. from django.utils import six
  5. from django.utils.encoding import force_text
  6. class FieldDoesNotExist(Exception):
  7. """The requested model field does not exist"""
  8. pass
  9. class DjangoRuntimeWarning(RuntimeWarning):
  10. pass
  11. class AppRegistryNotReady(Exception):
  12. """The django.apps registry is not populated yet"""
  13. pass
  14. class ObjectDoesNotExist(Exception):
  15. """The requested object does not exist"""
  16. silent_variable_failure = True
  17. class MultipleObjectsReturned(Exception):
  18. """The query returned multiple objects when only one was expected."""
  19. pass
  20. class SuspiciousOperation(Exception):
  21. """The user did something suspicious"""
  22. class SuspiciousMultipartForm(SuspiciousOperation):
  23. """Suspect MIME request in multipart form data"""
  24. pass
  25. class SuspiciousFileOperation(SuspiciousOperation):
  26. """A Suspicious filesystem operation was attempted"""
  27. pass
  28. class DisallowedHost(SuspiciousOperation):
  29. """HTTP_HOST header contains invalid value"""
  30. pass
  31. class DisallowedRedirect(SuspiciousOperation):
  32. """Redirect to scheme not in allowed list"""
  33. pass
  34. class TooManyFieldsSent(SuspiciousOperation):
  35. """
  36. The number of fields in a POST request exceeded
  37. settings.DATA_UPLOAD_MAX_NUMBER_FIELDS.
  38. """
  39. pass
  40. class RequestDataTooBig(SuspiciousOperation):
  41. """
  42. The size of the request (excluding any file uploads) exceeded
  43. settings.DATA_UPLOAD_MAX_MEMORY_SIZE.
  44. """
  45. pass
  46. class PermissionDenied(Exception):
  47. """The user did not have permission to do that"""
  48. pass
  49. class ViewDoesNotExist(Exception):
  50. """The requested view does not exist"""
  51. pass
  52. class MiddlewareNotUsed(Exception):
  53. """This middleware is not used in this server configuration"""
  54. pass
  55. class ImproperlyConfigured(Exception):
  56. """Django is somehow improperly configured"""
  57. pass
  58. class FieldError(Exception):
  59. """Some kind of problem with a model field."""
  60. pass
  61. NON_FIELD_ERRORS = '__all__'
  62. class ValidationError(Exception):
  63. """An error while validating data."""
  64. def __init__(self, message, code=None, params=None):
  65. """
  66. The `message` argument can be a single error, a list of errors, or a
  67. dictionary that maps field names to lists of errors. What we define as
  68. an "error" can be either a simple string or an instance of
  69. ValidationError with its message attribute set, and what we define as
  70. list or dictionary can be an actual `list` or `dict` or an instance
  71. of ValidationError with its `error_list` or `error_dict` attribute set.
  72. """
  73. # PY2 can't pickle naive exception: http://bugs.python.org/issue1692335.
  74. super(ValidationError, self).__init__(message, code, params)
  75. if isinstance(message, ValidationError):
  76. if hasattr(message, 'error_dict'):
  77. message = message.error_dict
  78. # PY2 has a `message` property which is always there so we can't
  79. # duck-type on it. It was introduced in Python 2.5 and already
  80. # deprecated in Python 2.6.
  81. elif not hasattr(message, 'message' if six.PY3 else 'code'):
  82. message = message.error_list
  83. else:
  84. message, code, params = message.message, message.code, message.params
  85. if isinstance(message, dict):
  86. self.error_dict = {}
  87. for field, messages in message.items():
  88. if not isinstance(messages, ValidationError):
  89. messages = ValidationError(messages)
  90. self.error_dict[field] = messages.error_list
  91. elif isinstance(message, list):
  92. self.error_list = []
  93. for message in message:
  94. # Normalize plain strings to instances of ValidationError.
  95. if not isinstance(message, ValidationError):
  96. message = ValidationError(message)
  97. if hasattr(message, 'error_dict'):
  98. self.error_list.extend(sum(message.error_dict.values(), []))
  99. else:
  100. self.error_list.extend(message.error_list)
  101. else:
  102. self.message = message
  103. self.code = code
  104. self.params = params
  105. self.error_list = [self]
  106. @property
  107. def message_dict(self):
  108. # Trigger an AttributeError if this ValidationError
  109. # doesn't have an error_dict.
  110. getattr(self, 'error_dict')
  111. return dict(self)
  112. @property
  113. def messages(self):
  114. if hasattr(self, 'error_dict'):
  115. return sum(dict(self).values(), [])
  116. return list(self)
  117. def update_error_dict(self, error_dict):
  118. if hasattr(self, 'error_dict'):
  119. for field, error_list in self.error_dict.items():
  120. error_dict.setdefault(field, []).extend(error_list)
  121. else:
  122. error_dict.setdefault(NON_FIELD_ERRORS, []).extend(self.error_list)
  123. return error_dict
  124. def __iter__(self):
  125. if hasattr(self, 'error_dict'):
  126. for field, errors in self.error_dict.items():
  127. yield field, list(ValidationError(errors))
  128. else:
  129. for error in self.error_list:
  130. message = error.message
  131. if error.params:
  132. message %= error.params
  133. yield force_text(message)
  134. def __str__(self):
  135. if hasattr(self, 'error_dict'):
  136. return repr(dict(self))
  137. return repr(list(self))
  138. def __repr__(self):
  139. return 'ValidationError(%s)' % self