Coverage for dcim/fields.py: 81%

60 statements  

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

1from django.contrib.postgres.fields import ArrayField 

2from django.core.exceptions import ValidationError 

3from django.db import models 

4from django.utils.translation import gettext as _ 

5from netaddr import EUI, AddrFormatError, eui64_unix_expanded, mac_unix_expanded 

6 

7from .lookups import PathContains 

8 

9__all__ = ( 

10 'MACAddressField', 

11 'PathField', 

12 'WWNField', 

13) 

14 

15 

16class mac_unix_expanded_uppercase(mac_unix_expanded): 

17 word_fmt = '%.2X' 

18 

19 

20class eui64_unix_expanded_uppercase(eui64_unix_expanded): 

21 word_fmt = '%.2X' 

22 

23 

24# 

25# Fields 

26# 

27 

28class MACAddressField(models.Field): 

29 description = 'PostgreSQL MAC Address field' 

30 

31 def python_type(self): 

32 return EUI 

33 

34 def from_db_value(self, value, expression, connection): 

35 return self.to_python(value) 

36 

37 def get_internal_type(self): 

38 return 'CharField' 

39 

40 def to_python(self, value): 

41 if value is None: 41 ↛ 42line 41 didn't jump to line 42 because the condition on line 41 was never true

42 return value 

43 if type(value) is str: 43 ↛ 45line 43 didn't jump to line 45 because the condition on line 43 was always true

44 value = value.replace(' ', '') 

45 try: 

46 return EUI(value, version=48, dialect=mac_unix_expanded_uppercase) 

47 except AddrFormatError: 

48 raise ValidationError(_("Invalid MAC address format: {value}").format(value=value)) 

49 

50 def db_type(self, connection): 

51 return 'macaddr' 

52 

53 def get_prep_value(self, value): 

54 if not value: 

55 return None 

56 return str(self.to_python(value)) 

57 

58 

59class WWNField(models.Field): 

60 description = 'World Wide Name field' 

61 

62 def python_type(self): 

63 return EUI 

64 

65 def from_db_value(self, value, expression, connection): 

66 return self.to_python(value) 

67 

68 def get_internal_type(self): 

69 return 'CharField' 

70 

71 def to_python(self, value): 

72 if value is None: 72 ↛ 74line 72 didn't jump to line 74 because the condition on line 72 was always true

73 return value 

74 try: 

75 return EUI(value, version=64, dialect=eui64_unix_expanded_uppercase) 

76 except AddrFormatError: 

77 raise ValidationError(_("Invalid WWN format: {value}").format(value=value)) 

78 

79 def db_type(self, connection): 

80 return 'macaddr8' 

81 

82 def get_prep_value(self, value): 

83 if not value: 83 ↛ 85line 83 didn't jump to line 85 because the condition on line 83 was always true

84 return None 

85 return str(self.to_python(value)) 

86 

87 

88class PathField(ArrayField): 

89 """ 

90 An ArrayField which holds a set of objects, each identified by a (type, ID) tuple. 

91 """ 

92 def __init__(self, **kwargs): 

93 kwargs['base_field'] = models.CharField(max_length=40) 

94 super().__init__(**kwargs) 

95 

96 

97PathField.register_lookup(PathContains)