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
« 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"""
8import random
9import sys
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
18from django.db import models
19from django.db.models.fields import ( # noqa: F401
20 BLANK_CHOICE_DASH,
21 NOT_PROVIDED,
22 __all__,
23)
25from audoma.django import forms
26from audoma.example_generators import generate_lorem_ipsum
27from audoma.mixins import ModelExampleMixin
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
41this = sys.modules[__name__]
44for field_name in __all__:
45 if field_name in ["BLANK_CHOICE_DASH", "NOT_PROVIDED"]:
46 continue
48 setattr(
49 this,
50 field_name,
51 type(field_name, (ModelExampleMixin, getattr(models, field_name)), {}),
52 )
55__all__.extend(["MoneyField", "CurrencyField", "PhoneNumberField", "MACAddressField"])
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)
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 """
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
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)
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))
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)
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()
122class MACAddressField(ModelExampleMixin, MACAddressField): # pragma: no cover
123 pass
126class JSONField(ModelExampleMixin, JSONField): # pragma: no cover
127 pass
130if "JSONField" not in __all__:
131 __all__.append("JSONField")