Coverage for audoma/drf/fields.py: 37%
27 statements
« prev ^ index » next coverage.py v6.4.2, created at 2022-08-08 06:12 +0000
« prev ^ index » next coverage.py v6.4.2, created at 2022-08-08 06:12 +0000
1"""
2This module is an override for default drf's field module.
3Most of those fields, are providing additional example functionality,
4and also has defined schema type.
5"""
7import sys
9import exrex
10import phonenumbers
11from djmoney.contrib.django_rest_framework import MoneyField
12from drf_spectacular.types import OpenApiTypes
13from drf_spectacular.utils import extend_schema_field
14from phonenumber_field import serializerfields
15from phonenumber_field.phonenumber import to_python
16from rest_framework import fields
17from rest_framework.fields import * # noqa: F403, F401
19from django.core import validators
21from audoma.example_generators import generate_lorem_ipsum
22from audoma.mixins import (
23 ExampleMixin,
24 NumericExampleMixin,
25 RegexExampleMixin,
26)
29field_names = [
30 "BooleanField",
31 "NullBooleanField",
32 "EmailField",
33 "SlugField",
34 "URLField",
35 "DateTimeField",
36 "DurationField",
37 "ChoiceField",
38 "MultipleChoiceField",
39 "FilePathField",
40 "FileField",
41 "ImageField",
42 "ListField",
43 "DictField",
44 "HStoreField",
45 "JSONField",
46 "ReadOnlyField",
47 "SerializerMethodField",
48] # pragma: no cover
51this = sys.modules[__name__] # pragma: no cover
54for field_name in field_names: # pragma: no cover
56 setattr(
57 this,
58 field_name,
59 type(field_name, (ExampleMixin, getattr(fields, field_name)), {}),
60 )
63class DecimalField(NumericExampleMixin, fields.DecimalField): # pragma: no cover
64 pass
67@extend_schema_field(OpenApiTypes.UUID) # pragma: no cover
68class UUIDField(ExampleMixin, fields.UUIDField): # pragma: no cover
69 pass
72class IntegerField(NumericExampleMixin, fields.IntegerField): # pragma: no cover
73 pass
76class FloatField(NumericExampleMixin, fields.FloatField): # pragma: no cover
77 pass
80class RegexField(RegexExampleMixin, fields.RegexField): # pragma: no cover
81 pass
84class MACAddressField(RegexExampleMixin, fields.CharField): # pragma: no cover
85 def __init__(self, **kwargs) -> None:
86 self.regex = "^([0-9A-F]{2}:){5}([0-9A-F]{2})|([0-9A-F]{2}-){5}([0-9A-F]{2})$"
87 self.validators = [validators.RegexValidator(self.regex)]
88 super().__init__(**kwargs)
91@extend_schema_field(OpenApiTypes.DATE) # pragma: no cover
92class DateField(ExampleMixin, fields.DateField): # pragma: no cover
93 pass
96@extend_schema_field(OpenApiTypes.TIME) # pragma: no cover
97class TimeField(ExampleMixin, fields.TimeField): # pragma: no cover
98 pass
101@extend_schema_field(
102 field={
103 "format": "ip-address",
104 "example": str(
105 exrex.getone(
106 r"^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$"
107 )
108 ),
109 }
110) # pragma: no cover
111class IPAddressField(ExampleMixin, fields.IPAddressField): # pragma: no cover
112 pass
115@extend_schema_field(field={"format": "tel"}) # pragma: no cover
116class PhoneNumberField(ExampleMixin, serializerfields.PhoneNumberField):
117 def __init__(self, *args, **kwargs) -> None:
118 example = kwargs.pop("example", None)
119 if example is None:
120 number = phonenumbers.example_number(None)
121 example = str(to_python(number))
122 super().__init__(*args, example=example, **kwargs)
125class CharField(ExampleMixin, fields.CharField):
126 def __init__(self, *args, **kwargs) -> None:
127 example = kwargs.pop("example", None)
128 min_length = kwargs.get("min_length", 20)
129 max_length = kwargs.get("max_length", 80)
130 if not example:
131 example = generate_lorem_ipsum(min_length=min_length, max_length=max_length)
133 super().__init__(*args, example=example, **kwargs)
136class MoneyField(NumericExampleMixin, MoneyField): # pragma: no cover
137 pass
140class ChoiceField(ExampleMixin, fields.ChoiceField):
141 def __init__(self, choices, **kwargs):
142 if isinstance(choices, dict):
143 self.original_choices = list(choices.items())
144 else:
145 self.original_choices = choices
146 super().__init__(choices, **kwargs)