Coverage for ipam/formfields.py: 23%

38 statements  

« prev     ^ index     » next       coverage.py v7.15.2, created at 2026-10-10 18:35 +0000

1from django import forms 

2from django.core.exceptions import ValidationError 

3from django.core.validators import validate_ipv4_address, validate_ipv6_address 

4from django.utils.translation import gettext_lazy as _ 

5from netaddr import AddrFormatError, IPAddress, IPNetwork 

6 

7# 

8# Form fields 

9# 

10 

11 

12class IPAddressFormField(forms.Field): 

13 default_error_messages = { 

14 'invalid': _("Enter a valid IPv4 or IPv6 address (without a mask)."), 

15 } 

16 

17 def to_python(self, value): 

18 if not value: 

19 return None 

20 

21 if isinstance(value, IPAddress): 

22 return value 

23 

24 # netaddr is a bit too liberal with what it accepts as a valid IP address. For example, '1.2.3' will become 

25 # IPAddress('1.2.0.3'). Here, we employ Django's built-in IPv4 and IPv6 address validators as a sanity check. 

26 try: 

27 validate_ipv4_address(value) 

28 except ValidationError: 

29 try: 

30 validate_ipv6_address(value) 

31 except ValidationError: 

32 raise ValidationError(_("Invalid IPv4/IPv6 address format: {address}").format(address=value)) 

33 

34 try: 

35 return IPAddress(value) 

36 except ValueError: 

37 raise ValidationError(_('This field requires an IP address without a mask.')) 

38 except AddrFormatError: 

39 raise ValidationError(_("Please specify a valid IPv4 or IPv6 address.")) 

40 

41 

42class IPNetworkFormField(forms.Field): 

43 default_error_messages = { 

44 'invalid': _("Enter a valid IPv4 or IPv6 address (with CIDR mask)."), 

45 } 

46 

47 def to_python(self, value): 

48 if not value: 

49 return None 

50 

51 if isinstance(value, IPNetwork): 

52 return value 

53 

54 # Ensure that a subnet mask has been specified. This prevents IPs from defaulting to a /32 or /128. 

55 if len(value.split('/')) != 2: 

56 raise ValidationError(_('CIDR mask (e.g. /24) is required.')) 

57 

58 try: 

59 return IPNetwork(value) 

60 except AddrFormatError: 

61 raise ValidationError(_("Please specify a valid IPv4 or IPv6 address."))