Skip to content

Commit 009e50d

Browse files
committed
[FEATURE] Generate same data for object in every run.
1 parent 15c3644 commit 009e50d

File tree

4 files changed

+51
-3
lines changed

4 files changed

+51
-3
lines changed

README.md

+18
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,24 @@ class YourModelAnonymizer(Anonymizer):
5252
return super().get_queryset().filter(is_staff=True)
5353
```
5454

55+
## Faker seed
56+
57+
Default it will use the object id as seed, to generate the same data for every run.
58+
You can disable this by overriding the `get_object_seed` and return falsy value.
59+
60+
```python
61+
from django_anonymous import Anonymizer, Faker, register
62+
from .model import YourModel
63+
64+
65+
@register(YourModel)
66+
class YourModelAnonymizer(Anonymizer):
67+
email = Faker("email", unique=True)
68+
69+
def get_object_seed(self, obj):
70+
return None
71+
```
72+
5573
## Settings for Anonymizer
5674

5775
Per Anonymizer you can set the select chunk size and update batch size.

django_anonymous/anonymizer.py

+4-1
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,13 @@ def get_batches(self):
3838
if batch:
3939
yield batch
4040

41+
def get_object_seed(self, obj):
42+
return obj.id
43+
4144
def anonymize_object(self, obj):
4245
for field, value in self._fields.items():
4346
if callable(value):
44-
new_value = value()
47+
new_value = value(obj, self.get_object_seed(obj))
4548
else:
4649
new_value = value
4750

django_anonymous/faker.py

+4-2
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,15 @@ def __init__(self, provider, **kwargs):
1414
self.unique = kwargs.pop("unique", False)
1515
self.kwargs = kwargs
1616

17-
def __call__(self):
17+
def __call__(self, obj, seed=None):
1818
local_faker = self._get_faker()
19+
if seed:
20+
local_faker.seed_instance(seed)
1921
if self.unique:
2022
local_faker = local_faker.unique
2123
return local_faker.format(self.provider, **self.kwargs)
2224

23-
def _get_faker(self):
25+
def _get_faker(self) -> faker.Faker:
2426
if self.locale not in self._FAKER_REGISTRY:
2527
self._FAKER_REGISTRY[self.locale] = faker.Faker(locale=self.locale)
2628
return self._FAKER_REGISTRY[self.locale]

test_project/test_anonymizer.py

+25
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
from django.core.management import call_command
33

44
from django_anonymous.register import load_anonymizer, register, registered_models
5+
from test_project.anon import ItemAnonymizer
56
from test_project.models import Item, Order
67

78

@@ -48,3 +49,27 @@ def test_anonymizer():
4849
assert item.order_id == new_item.order_id
4950
assert item.description != new_item.description
5051
assert 25 == new_item.amount
52+
53+
54+
@pytest.mark.django_db
55+
def test_anonymizer_seed():
56+
item = Item.objects.create(
57+
order=Order.objects.create(first_name="Master", last_name="Chief"),
58+
description="test",
59+
amount=12.50,
60+
)
61+
anon = ItemAnonymizer(Item)
62+
63+
anon.anonymize_object(item)
64+
assert item.description != "test"
65+
66+
# Should generate same description
67+
seed_description = item.description
68+
item.description = "test"
69+
anon.anonymize_object(item)
70+
assert item.description == seed_description
71+
72+
# Should generate different description
73+
item.id = item.id + 1
74+
anon.anonymize_object(item)
75+
assert item.description != seed_description

0 commit comments

Comments
 (0)