Commit b102c27f authored by Si Feng's avatar Si Feng Committed by Tim Graham
Browse files

Fixed #20784 -- Added inverse_match parameter to RegexValidator.

parent 0d98422b
Loading
Loading
Loading
Loading
+8 −3
Original line number Diff line number Diff line
@@ -20,14 +20,17 @@ class RegexValidator(object):
    regex = ''
    message = _('Enter a valid value.')
    code = 'invalid'
    inverse_match = False

    def __init__(self, regex=None, message=None, code=None):
    def __init__(self, regex=None, message=None, code=None, inverse_match=None):
        if regex is not None:
            self.regex = regex
        if message is not None:
            self.message = message
        if code is not None:
            self.code = code
        if inverse_match is not None:
            self.inverse_match = inverse_match

        # Compile the regex if it was not passed pre-compiled.
        if isinstance(self.regex, six.string_types):
@@ -35,9 +38,11 @@ class RegexValidator(object):

    def __call__(self, value):
        """
        Validates that the input matches the regular expression.
        Validates that the input matches the regular expression
        if inverse_match is False, otherwise raises ValidationError.
        """
        if not self.regex.search(force_text(value)):
        if not (self.inverse_match is not bool(self.regex.search(
                force_text(value)))):
            raise ValidationError(self.message, code=self.code)

    def __eq__(self, other):
+11 −3
Original line number Diff line number Diff line
@@ -59,20 +59,22 @@ to, or in lieu of custom ``field.clean()`` methods.

``RegexValidator``
------------------
.. class:: RegexValidator([regex=None, message=None, code=None])
.. class:: RegexValidator([regex=None, message=None, code=None, inverse_match=None])

    :param regex: If not ``None``, overrides :attr:`regex`. Can be a regular
        expression string or a pre-compiled regular expression.
    :param message: If not ``None``, overrides :attr:`.message`.
    :param code: If not ``None``, overrides :attr:`code`.
    :param inverse_match: If not ``None``, overrides :attr:`inverse_match`.

    .. attribute:: regex

        The regular expression pattern to search for the provided ``value``,
        or a pre-compiled regular expression. Raises a
        :exc:`~django.core.exceptions.ValidationError` with :attr:`message`
        and :attr:`code` if no match is found. By default, matches any string
        (including an empty string).
        and :attr:`code` if :attr:`inverse_match` is ``False`` and a match is
        found, or if :attr:`inverse_match` is ``True`` and a match is not found.
        By default, matches any string (including an empty string).

    .. attribute:: message

@@ -85,6 +87,12 @@ to, or in lieu of custom ``field.clean()`` methods.
        The error code used by :exc:`~django.core.exceptions.ValidationError`
        if validation fails. Defaults to ``"invalid"``.

    .. attribute:: inverse_match

        .. versionadded:: 1.7

        The match mode for :attr:`regex`. Defaults to ``False``.

``URLValidator``
----------------
.. class:: URLValidator([schemes=None, regex=None, message=None, code=None])
+6 −0
Original line number Diff line number Diff line
@@ -697,6 +697,12 @@ Tests
Validators
^^^^^^^^^^

* :class:`~django.core.validators.RegexValidator` now accepts an optional
  Boolean :attr:`~django.core.validators.RegexValidator.inverse_match` argument
  which determines if the :exc:`~django.core.exceptions.ValidationError` should
  be raised when the regular expression pattern matches (``True``) or does not
  match (``False``, by default) the provided ``value``.

* :class:`~django.core.validators.URLValidator` now accepts an optional
  ``schemes`` argument which allows customization of the accepted URI schemes
  (instead of the defaults ``http(s)`` and ``ftp(s)``).
+4 −0
Original line number Diff line number Diff line
@@ -187,6 +187,10 @@ TEST_DATA = (

    (RegexValidator('x'), 'y', ValidationError),
    (RegexValidator(re.compile('x')), 'y', ValidationError),
    (RegexValidator('x', inverse_match=True), 'y', None),
    (RegexValidator(re.compile('x'), inverse_match=True), 'y', None),
    (RegexValidator('x', inverse_match=True), 'x', ValidationError),
    (RegexValidator(re.compile('x'), inverse_match=True), 'x', ValidationError),
)