-
-
Notifications
You must be signed in to change notification settings - Fork 7k
add IPAddressField, update docs #2618
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,12 +2,13 @@ | |
from django.conf import settings | ||
from django.core.exceptions import ObjectDoesNotExist | ||
from django.core.exceptions import ValidationError as DjangoValidationError | ||
from django.core.validators import RegexValidator | ||
from django.core.validators import RegexValidator, ip_address_validators | ||
from django.forms import ImageField as DjangoImageField | ||
from django.utils import six, timezone | ||
from django.utils.dateparse import parse_date, parse_datetime, parse_time | ||
from django.utils.encoding import is_protected_type, smart_text | ||
from django.utils.translation import ugettext_lazy as _ | ||
from django.utils.ipv6 import clean_ipv6_address | ||
from rest_framework import ISO_8601 | ||
from rest_framework.compat import ( | ||
EmailValidator, MinValueValidator, MaxValueValidator, | ||
|
@@ -653,6 +654,30 @@ def to_representation(self, value): | |
return str(value) | ||
|
||
|
||
class IPAddressField(CharField): | ||
"""Support both IPAddressField and GenericIPAddressField""" | ||
|
||
default_error_messages = { | ||
'invalid': _('Enter a valid IPv4 or IPv6 address.'), | ||
} | ||
|
||
def __init__(self, protocol='both', unpack_ipv4=False, **kwargs): | ||
self.protocol = protocol | ||
self.unpack_ipv4 = unpack_ipv4 | ||
super(IPAddressField, self).__init__(**kwargs) | ||
validators, error_message = ip_address_validators(protocol, unpack_ipv4) | ||
self.validators.extend(validators) | ||
|
||
def to_internal_value(self, data): | ||
if data and ':' in data: | ||
try: | ||
return clean_ipv6_address(data, self.unpack_ipv4) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this should be changed to:
or we just "clean" the ipv6 address without validating it. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I made a wrong assumption. is_valid_ipv6_address is called from clean_ipv6_address https://github.com/django/django/blob/0ed7d155635da9f79d4dd67e4889087d3673c6da/django/utils/ipv6.py#L35 |
||
except DjangoValidationError: | ||
self.fail('invalid', value=data) | ||
|
||
return super(IPAddressField, self).to_internal_value(data) | ||
|
||
|
||
# Number types... | ||
|
||
class IntegerField(Field): | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I may be wrong, but this line looks like we assume the user will always use 'both' protocol, but what happen if we can't unpack the ipv4 address to an ipv6 one? In this case ':' won't be present inside the ip string and the whole check will fail or be skipped.
Is this situation already handled by the use of ip_address_validators method? Should we add a particular test case that handle the situation where the user pass (protocol='ipv4', unpack_ipv4=True) ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sounds right!