You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

validators.py 3.2KB

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