您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

validators.py 3.6KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. from django.core import validators
  2. from django.core.exceptions import ValidationError
  3. from django.core.urlresolvers import resolve
  4. from django.db.models import get_model
  5. from django.http import Http404
  6. from django.utils.translation import ugettext_lazy as _
  7. class ExtendedURLValidator(validators.URLValidator):
  8. def __init__(self, *args, **kwargs):
  9. # 'verify_exists' has been removed in Django 1.5 and so we no longer
  10. # pass it up to the core validator class
  11. self.is_local_url = False
  12. self.verify_exists = kwargs.pop('verify_exists', False)
  13. super(ExtendedURLValidator, self).__init__(*args, **kwargs)
  14. def __call__(self, value):
  15. try:
  16. super(ExtendedURLValidator, self).__call__(value)
  17. except ValidationError:
  18. # The parent validator will raise an exception if the URL does not
  19. # exist and so we test here to see if the value is a local URL.
  20. if self.verify_exists and value:
  21. self.validate_local_url(value)
  22. else:
  23. raise
  24. def validate_local_url(self, value):
  25. value = self.clean_url(value)
  26. try:
  27. resolve(value)
  28. except Http404:
  29. # We load flatpages here as it causes a circular reference problem
  30. # sometimes. FlatPages is None if not installed
  31. FlatPage = get_model('flatpages', 'FlatPage')
  32. if FlatPage is not None:
  33. try:
  34. FlatPage.objects.get(url=value)
  35. except FlatPage.DoesNotExist:
  36. self.is_local_url = True
  37. else:
  38. return
  39. raise ValidationError(_('Specified page does not exist'))
  40. else:
  41. self.is_local_url = True
  42. def clean_url(self, value):
  43. """
  44. Ensure url has a preceding slash and no query string
  45. """
  46. if value != '/':
  47. value = '/' + value.lstrip('/')
  48. q_index = value.find('?')
  49. if q_index > 0:
  50. value = value[:q_index]
  51. return value
  52. class URLDoesNotExistValidator(ExtendedURLValidator):
  53. def __call__(self, value):
  54. """
  55. Validate that the URL in *value* does not already exist. The
  56. URL will be verified first and raises ``ValidationError`` when
  57. it is invalid. A valid URL is checked for existance and raises
  58. ``ValidationError`` if the URL already exists. Setting attribute
  59. ``verify_exists`` has no impact on validation.
  60. This validation uses two calls to ExtendedURLValidator which can
  61. be slow. Be aware of this, when you use it.
  62. Returns ``None`` if URL is valid and does not exist.
  63. """
  64. self.verify_exists = False
  65. # calling ExtendedURLValidator twice instead of replicating its code
  66. # and invert the cases when a ValidationError is returned seemes to
  67. # be a much cleaner solution. Although this might not be the most
  68. # efficient way of handling this, it should have not much of an impact
  69. # due to its current application in flatpage creation.
  70. try:
  71. super(URLDoesNotExistValidator, self).__call__(value)
  72. except ValidationError:
  73. raise ValidationError(_('Specified page does already exist'),
  74. code='invalid')
  75. # check if URL exists since it seems to be valid
  76. try:
  77. self.verify_exists = True
  78. super(URLDoesNotExistValidator, self).__call__(value)
  79. except ValidationError:
  80. return
  81. raise ValidationError(_('Specified page does already exist'),
  82. code='invalid')