|
2 | 2 | from django.conf import settings |
3 | 3 | from django.core.exceptions import ObjectDoesNotExist |
4 | 4 | from django.core.exceptions import ValidationError as DjangoValidationError |
5 | | -from django.core.validators import RegexValidator |
| 5 | +from django.core.validators import RegexValidator, ip_address_validators |
6 | 6 | from django.forms import ImageField as DjangoImageField |
7 | 7 | from django.utils import six, timezone |
8 | 8 | from django.utils.dateparse import parse_date, parse_datetime, parse_time |
9 | 9 | from django.utils.encoding import is_protected_type, smart_text |
10 | 10 | from django.utils.translation import ugettext_lazy as _ |
| 11 | +from django.utils.ipv6 import clean_ipv6_address |
11 | 12 | from rest_framework import ISO_8601 |
12 | 13 | from rest_framework.compat import ( |
13 | 14 | EmailValidator, MinValueValidator, MaxValueValidator, |
@@ -672,6 +673,31 @@ def to_representation(self, value): |
672 | 673 | return getattr(value, self.uuid_format) |
673 | 674 |
|
674 | 675 |
|
| 676 | +class IPAddressField(CharField): |
| 677 | + """Support both IPAddressField and GenericIPAddressField""" |
| 678 | + |
| 679 | + default_error_messages = { |
| 680 | + 'invalid': _('Enter a valid IPv4 or IPv6 address.'), |
| 681 | + } |
| 682 | + |
| 683 | + def __init__(self, protocol='both', **kwargs): |
| 684 | + self.protocol = protocol.lower() |
| 685 | + self.unpack_ipv4 = (self.protocol == 'both') |
| 686 | + super(IPAddressField, self).__init__(**kwargs) |
| 687 | + validators, error_message = ip_address_validators(protocol, self.unpack_ipv4) |
| 688 | + self.validators.extend(validators) |
| 689 | + |
| 690 | + def to_internal_value(self, data): |
| 691 | + if data and ':' in data: |
| 692 | + try: |
| 693 | + if self.protocol in ('both', 'ipv6'): |
| 694 | + return clean_ipv6_address(data, self.unpack_ipv4) |
| 695 | + except DjangoValidationError: |
| 696 | + self.fail('invalid', value=data) |
| 697 | + |
| 698 | + return super(IPAddressField, self).to_internal_value(data) |
| 699 | + |
| 700 | + |
675 | 701 | # Number types... |
676 | 702 |
|
677 | 703 | class IntegerField(Field): |
|
0 commit comments