Coverage for audoma/django/db/fields.py: 39%

67 statements  

« prev     ^ index     » next       coverage.py v6.4.2, created at 2022-08-04 08:25 +0000

1"""Audoma Django model Fields 

2This module contains all the fields from Django models with additional functionality. 

3By inheriting from Audoma Mixins, an example is generated for each field (i.e. FloatField will have 

4example generated based on field's min and max values). 

5We can define custom example by simply passing `example` as an argument to the field. 

6""" 

7 

8import random 

9import sys 

10 

11import phonenumbers 

12from djmoney.models import fields as djmoney_fields 

13from djmoney.utils import get_currency_field_name 

14from macaddress.fields import MACAddressField 

15from phonenumber_field.modelfields import PhoneNumberField 

16from phonenumber_field.phonenumber import to_python 

17 

18from django.db import models 

19from django.db.models.fields import ( # noqa: F401 

20 BLANK_CHOICE_DASH, 

21 NOT_PROVIDED, 

22 __all__, 

23) 

24 

25from audoma.django import forms 

26from audoma.example_generators import generate_lorem_ipsum 

27from audoma.mixins import ModelExampleMixin 

28 

29 

30try: 

31 from django.db.models import JSONField 

32except ImportError: 

33 try: 

34 from jsonfield import JSONField 

35 except ImportError as err: 

36 raise ImportError( 

37 "You are using old version of Django that doesn't support JSONField. Please install django-jsonfield" 

38 ) from err 

39 

40 

41this = sys.modules[__name__] 

42 

43 

44for field_name in __all__: 

45 if field_name in ["BLANK_CHOICE_DASH", "NOT_PROVIDED"]: 

46 continue 

47 

48 setattr( 

49 this, 

50 field_name, 

51 type(field_name, (ModelExampleMixin, getattr(models, field_name)), {}), 

52 ) 

53 

54 

55__all__.extend(["MoneyField", "CurrencyField", "PhoneNumberField", "MACAddressField"]) 

56 

57 

58class CurrencyField(ModelExampleMixin, djmoney_fields.CurrencyField): 

59 def __init__(self, *args, **kwargs) -> None: 

60 default = kwargs.get("default", None) 

61 if default and str(default) != "XYZ": 

62 self.example = default 

63 elif kwargs.get("choices", None): 

64 self.example = random.choice(kwargs["choices"])[0] 

65 else: 

66 self.example = "XYZ" 

67 super().__init__(*args, **kwargs) 

68 

69 

70class MoneyField(ModelExampleMixin, djmoney_fields.MoneyField): 

71 def add_currency_field(self, cls, name): 

72 """ 

73 Adds CurrencyField instance to a model class and creates example in documentation. 

74 """ 

75 

76 currency_field = CurrencyField( 

77 price_field=self, 

78 max_length=self.currency_max_length, 

79 default=self.default_currency, 

80 choices=self.currency_choices, 

81 null=self.default_currency is None, 

82 ) 

83 currency_field.creation_counter = self.creation_counter - 1 

84 currency_field_name = get_currency_field_name(name, self) 

85 cls.add_to_class(currency_field_name, currency_field) 

86 self._currency_field = currency_field 

87 

88 def formfield(self, **kwargs): 

89 defaults = { 

90 "form_class": forms.MoneyField, 

91 "decimal_places": self.decimal_places, 

92 } 

93 defaults.update(kwargs) 

94 if self._has_default: 

95 defaults["default_amount"] = self.default.amount 

96 return super(djmoney_fields.MoneyField, self).formfield(**defaults) 

97 

98 

99class PhoneNumberField(ModelExampleMixin, PhoneNumberField): 

100 def __init__(self, *args, region=None, **kwargs) -> None: 

101 super().__init__(*args, region=region, **kwargs) 

102 if not kwargs.get("example", None): 

103 number = phonenumbers.example_number(region) 

104 self.example = str(to_python(number)) 

105 

106 

107class CharField(ModelExampleMixin, models.CharField): 

108 def __init__(self, *args, **kwargs) -> None: 

109 super().__init__(*args, **kwargs) 

110 max_length = kwargs.get("max_length", 80) 

111 if not kwargs.get("example", None) and max_length: 

112 self.example = generate_lorem_ipsum(max_length=max_length) 

113 

114 

115class TextField(ModelExampleMixin, models.TextField): 

116 def __init__(self, *args, **kwargs) -> None: 

117 super().__init__(*args, **kwargs) 

118 if not kwargs.get("example", None): 

119 self.example = generate_lorem_ipsum() 

120 

121 

122class MACAddressField(ModelExampleMixin, MACAddressField): # pragma: no cover 

123 pass 

124 

125 

126class JSONField(ModelExampleMixin, JSONField): # pragma: no cover 

127 pass 

128 

129 

130if "JSONField" not in __all__: 

131 __all__.append("JSONField")