add IPAddressField, update docs

This commit is contained in:
Aider Ibragimov 2015-02-28 10:11:38 +03:00
parent aa7ed316d8
commit 4d5eee04a0
3 changed files with 63 additions and 2 deletions

View File

@ -188,6 +188,17 @@ A field that ensures the input is a valid UUID string. The `to_internal_value` m
"de305d54-75b4-431b-adb2-eb6b9e546013"
## IPAddressField
A field that ensures the input is a valid IPv4 or IPv6 string.
Corresponds to `django.forms.fields.IPAddressField` and `django.forms.fields.GenericIPAddressField`.
**Signature**: `IPAddressField(protocol='both', unpack_ipv4=False, **options)`
- `protocol` Limits valid inputs to the specified protocol. Accepted values are 'both' (default), 'IPv4' or 'IPv6'. Matching is case insensitive.
- `unpack_ipv4` Unpacks IPv4 mapped addresses like ::ffff:192.0.2.1. If this option is enabled that address would be unpacked to 192.0.2.1. Default is disabled. Can only be used when protocol is set to 'both'.
---
# Numeric fields

View File

@ -2,12 +2,13 @@ from __future__ import unicode_literals
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,
@ -650,6 +651,34 @@ class UUIDField(Field):
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 self.allow_blank:
return ''
data = data.strip()
if data and ':' in data:
try:
return clean_ipv6_address(data, self.unpack_ipv4)
except DjangoValidationError:
self.fail('invalid', value=data)
return data
# Number types...
class IntegerField(Field):

View File

@ -485,6 +485,27 @@ class TestUUIDField(FieldValues):
field = serializers.UUIDField()
class TestIPAddressField(FieldValues):
"""
Valid and invalid values for `IPAddressField`
"""
valid_inputs = {
'127.0.0.1': '127.0.0.1',
'192.168.33.255': '192.168.33.255',
'2001:0db8:85a3:0042:1000:8a2e:0370:7334': '2001:db8:85a3:42:1000:8a2e:370:7334',
'2001:cdba:0:0:0:0:3257:9652': '2001:cdba::3257:9652',
'2001:cdba::3257:9652': '2001:cdba::3257:9652'
}
invalid_inputs = {
'127001': ['Enter a valid IPv4 or IPv6 address.'],
'127.122.111.2231': ['Enter a valid IPv4 or IPv6 address.'],
'2001:::9652': ['Enter a valid IPv4 or IPv6 address.'],
'2001:0db8:85a3:0042:1000:8a2e:0370:73341': ['Enter a valid IPv4 or IPv6 address.'],
}
outputs = {}
field = serializers.IPAddressField()
# Number types...
class TestIntegerField(FieldValues):