Commit e25a938
committed
Ref #61 -- Introduce generators for each integer field
# Conflicts:
# model_bakery/random_gen.py
diff --git c/model_bakery/generators.py i/model_bakery/generators.py
index 087355e..619736a 100644
--- c/model_bakery/generators.py
+++ i/model_bakery/generators.py
@@ -2,7 +2,6 @@ from collections.abc import Callable
from decimal import Decimal
from typing import Any
-from django.db.backends.base.operations import BaseDatabaseOperations
from django.db.models import (
AutoField,
BigAutoField,
@@ -82,29 +81,20 @@ except ImportError:
IntegerRangeField = None
-def _make_integer_gen_by_range(field_type: Any) -> Callable:
- min_int, max_int = BaseDatabaseOperations.integer_field_ranges[field_type.__name__]
-
- def gen_integer():
- return random_gen.gen_integer(min_int=min_int, max_int=max_int)
-
- return gen_integer
-
-
default_mapping = {
ForeignKey: random_gen.gen_related,
OneToOneField: random_gen.gen_related,
ManyToManyField: random_gen.gen_m2m,
BooleanField: random_gen.gen_boolean,
- AutoField: _make_integer_gen_by_range(AutoField),
- BigAutoField: _make_integer_gen_by_range(BigAutoField),
- IntegerField: _make_integer_gen_by_range(IntegerField),
- SmallAutoField: _make_integer_gen_by_range(SmallAutoField),
- BigIntegerField: _make_integer_gen_by_range(BigIntegerField),
- SmallIntegerField: _make_integer_gen_by_range(SmallIntegerField),
- PositiveBigIntegerField: _make_integer_gen_by_range(PositiveBigIntegerField),
- PositiveIntegerField: _make_integer_gen_by_range(PositiveIntegerField),
- PositiveSmallIntegerField: _make_integer_gen_by_range(PositiveSmallIntegerField),
+ AutoField: random_gen.gen_auto_field,
+ BigAutoField: random_gen.gen_positive_big_integer,
+ IntegerField: random_gen.gen_regular_integer,
+ SmallAutoField: random_gen.gen_positive_small_integer,
+ BigIntegerField: random_gen.gen_big_integer,
+ SmallIntegerField: random_gen.gen_small_integer,
+ PositiveBigIntegerField: random_gen.gen_positive_big_integer,
+ PositiveIntegerField: random_gen.gen_positive_integer,
+ PositiveSmallIntegerField: random_gen.gen_positive_small_integer,
FloatField: random_gen.gen_float,
DecimalField: random_gen.gen_decimal,
BinaryField: random_gen.gen_byte_string,
diff --git c/model_bakery/random_gen.py i/model_bakery/random_gen.py
index 278e604..59f9bdf 100644
--- c/model_bakery/random_gen.py
+++ i/model_bakery/random_gen.py
@@ -86,9 +86,87 @@ def gen_from_choices(
def gen_integer(min_int: int = -MAX_INT, max_int: int = MAX_INT) -> int:
+ warnings.warn(
+ "gen_integer() may cause overflow errors with Django integer fields due to "
+ "large default MAX_INT value. Consider using field-specific generators instead:\n"
+ "- gen_positive_small_integer() for PositiveSmallIntegerField\n"
+ "- gen_small_integer() for SmallIntegerField\n"
+ "- gen_regular_integer() for IntegerField\n"
+ "- gen_positive_integer() for PositiveIntegerField\n"
+ "- gen_big_integer() for BigIntegerField\n"
+ "- gen_positive_big_integer() for PositiveBigIntegerField\n"
+ "See model_bakery.random_gen documentation for more details.",
+ DeprecationWarning,
+ stacklevel=2,
+ )
return baker_random.randint(min_int, max_int)
+def _get_field_range(field_name: str):
+ """Get field range from Django's BaseDatabaseOperations."""
+ from django.db.backends.base.operations import BaseDatabaseOperations
+
+ return BaseDatabaseOperations.integer_field_ranges.get(
+ field_name, (-MAX_INT, MAX_INT)
+ )
+
+
+def gen_small_integer(min_int: int = None, max_int: int = None) -> int:
+ """Generate integer for SmallIntegerField."""
+ field_min, field_max = _get_field_range("SmallIntegerField")
+ actual_min = min_int if min_int is not None else field_min
+ actual_max = max_int if max_int is not None else field_max
+ return baker_random.randint(actual_min, actual_max)
+
+
+def gen_positive_small_integer(min_int: int = None, max_int: int = None) -> int:
+ """Generate integer for PositiveSmallIntegerField."""
+ field_min, field_max = _get_field_range("PositiveSmallIntegerField")
+ actual_min = min_int if min_int is not None else max(field_min, 1)
+ actual_max = max_int if max_int is not None else field_max
+ return baker_random.randint(actual_min, actual_max)
+
+
+def gen_positive_integer(min_int: int = None, max_int: int = None) -> int:
+ """Generate integer for PositiveIntegerField."""
+ field_min, field_max = _get_field_range("PositiveIntegerField")
+ actual_min = min_int if min_int is not None else max(field_min, 1)
+ actual_max = max_int if max_int is not None else field_max
+ return baker_random.randint(actual_min, actual_max)
+
+
+def gen_big_integer(min_int: int = None, max_int: int = None) -> int:
+ """Generate integer for BigIntegerField."""
+ field_min, field_max = _get_field_range("BigIntegerField")
+ actual_min = min_int if min_int is not None else field_min
+ actual_max = max_int if max_int is not None else field_max
+ return baker_random.randint(actual_min, actual_max)
+
+
+def gen_positive_big_integer(min_int: int = None, max_int: int = None) -> int:
+ """Generate integer for PositiveBigIntegerField."""
+ field_min, field_max = _get_field_range("PositiveBigIntegerField")
+ actual_min = min_int if min_int is not None else max(field_min, 1)
+ actual_max = max_int if max_int is not None else field_max
+ return baker_random.randint(actual_min, actual_max)
+
+
+def gen_regular_integer(min_int: int = None, max_int: int = None) -> int:
+ """Generate integer for IntegerField."""
+ field_min, field_max = _get_field_range("IntegerField")
+ actual_min = min_int if min_int is not None else field_min
+ actual_max = max_int if max_int is not None else field_max
+ return baker_random.randint(actual_min, actual_max)
+
+
+def gen_auto_field(min_int: int = None, max_int: int = None) -> int:
+ """Generate integer for AutoField."""
+ field_min, field_max = _get_field_range("AutoField")
+ actual_min = min_int if min_int is not None else max(field_min, 1)
+ actual_max = max_int if max_int is not None else field_max
+ return baker_random.randint(actual_min, actual_max)
+
+
def gen_float(min_float: float = -1000000.0, max_float: float = 1000000.0) -> float:
"""
Generate a random float uniformly distributed between `min_float` and `max_float`.
diff --git c/tests/test_baker.py i/tests/test_baker.py
index 71786bf..e1df809 100644
--- c/tests/test_baker.py
+++ i/tests/test_baker.py
@@ -1186,3 +1186,47 @@ class TestAutoNowFields:
assert instance.created == created
assert instance.updated == updated
assert instance.sent_date == sent_date
+
+
+class TestFieldSpecificIntegerGenerators:
+ @pytest.mark.django_db
+ def test_gen_positive_small_integer_works_safely(self):
+ obj = baker.make(
+ models.DummyPositiveIntModel,
+ positive_small_int_field=random_gen.gen_positive_small_integer(min_int=1),
+ )
+
+ assert 1 <= obj.positive_small_int_field <= 32767
+
+ def test_field_specific_generators_respect_constraints(self):
+ obj = baker.make(
+ models.DummyPositiveIntModel,
+ positive_small_int_field=random_gen.gen_positive_small_integer(
+ min_int=100, max_int=200
+ ),
+ )
+
+ assert 100 <= obj.positive_small_int_field <= 200
+
+ def test_gen_integer_shows_deprecation_warning(self):
+ import warnings
+
+ with warnings.catch_warnings(record=True) as w:
+ warnings.simplefilter("always")
+
+ # This should trigger the deprecation warning
+ value = random_gen.gen_integer(min_int=1, max_int=100)
+
+ assert len(w) == 1
+ assert issubclass(w[0].category, DeprecationWarning)
+ assert "gen_integer() may cause overflow errors" in str(w[0].message)
+ assert "gen_positive_small_integer()" in str(w[0].message)
+
+ assert 1 <= value <= 100
+
+ def test_automatic_generation_still_works(self):
+ obj = baker.make(models.DummyPositiveIntModel)
+
+ assert 1 <= obj.positive_small_int_field <= 32767
+ assert isinstance(obj.positive_int_field, int)
+ assert isinstance(obj.positive_big_int_field, int)1 parent 92c6a9b commit e25a938
File tree
3 files changed
+131
-19
lines changed- model_bakery
- tests
3 files changed
+131
-19
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
2 | 2 | | |
3 | 3 | | |
4 | 4 | | |
5 | | - | |
6 | 5 | | |
7 | 6 | | |
8 | 7 | | |
| |||
82 | 81 | | |
83 | 82 | | |
84 | 83 | | |
85 | | - | |
86 | | - | |
87 | | - | |
88 | | - | |
89 | | - | |
90 | | - | |
91 | | - | |
92 | | - | |
93 | | - | |
94 | 84 | | |
95 | 85 | | |
96 | 86 | | |
97 | 87 | | |
98 | 88 | | |
99 | | - | |
100 | | - | |
101 | | - | |
102 | | - | |
103 | | - | |
104 | | - | |
105 | | - | |
106 | | - | |
107 | | - | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
108 | 98 | | |
109 | 99 | | |
110 | 100 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
86 | 86 | | |
87 | 87 | | |
88 | 88 | | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
89 | 102 | | |
90 | 103 | | |
91 | 104 | | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
| 146 | + | |
| 147 | + | |
| 148 | + | |
| 149 | + | |
| 150 | + | |
| 151 | + | |
| 152 | + | |
| 153 | + | |
| 154 | + | |
| 155 | + | |
| 156 | + | |
| 157 | + | |
| 158 | + | |
| 159 | + | |
| 160 | + | |
| 161 | + | |
| 162 | + | |
| 163 | + | |
| 164 | + | |
| 165 | + | |
| 166 | + | |
| 167 | + | |
| 168 | + | |
| 169 | + | |
92 | 170 | | |
93 | 171 | | |
94 | 172 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1186 | 1186 | | |
1187 | 1187 | | |
1188 | 1188 | | |
| 1189 | + | |
| 1190 | + | |
| 1191 | + | |
| 1192 | + | |
| 1193 | + | |
| 1194 | + | |
| 1195 | + | |
| 1196 | + | |
| 1197 | + | |
| 1198 | + | |
| 1199 | + | |
| 1200 | + | |
| 1201 | + | |
| 1202 | + | |
| 1203 | + | |
| 1204 | + | |
| 1205 | + | |
| 1206 | + | |
| 1207 | + | |
| 1208 | + | |
| 1209 | + | |
| 1210 | + | |
| 1211 | + | |
| 1212 | + | |
| 1213 | + | |
| 1214 | + | |
| 1215 | + | |
| 1216 | + | |
| 1217 | + | |
| 1218 | + | |
| 1219 | + | |
| 1220 | + | |
| 1221 | + | |
| 1222 | + | |
| 1223 | + | |
| 1224 | + | |
| 1225 | + | |
| 1226 | + | |
| 1227 | + | |
| 1228 | + | |
| 1229 | + | |
| 1230 | + | |
| 1231 | + | |
| 1232 | + | |
0 commit comments