From 5c4ff1379b0d45ecf7c8901c2f3b63b406ef5e6c Mon Sep 17 00:00:00 2001 From: Florian Zimmermann Date: Sat, 16 Sep 2023 00:29:56 +0200 Subject: [PATCH] reuse lessons for base models when creating proxy models (#157) (#161) --- django_dynamic_fixture/ddf.py | 8 ++++++++ django_dynamic_fixture/models_test.py | 7 +++++++ .../tests/test_ddf_teaching_and_lessons.py | 18 ++++++++++++++++++ 3 files changed, 33 insertions(+) diff --git a/django_dynamic_fixture/ddf.py b/django_dynamic_fixture/ddf.py index 1e7f345..dd2d038 100644 --- a/django_dynamic_fixture/ddf.py +++ b/django_dynamic_fixture/ddf.py @@ -239,6 +239,7 @@ def add_configuration(self, model_class, kwargs, name=None): import warnings if name in [None, True]: name = self.DEFAULT_KEY + model_class = self._get_concrete_model(model_class) if model_class in self.configs and name in self.configs[model_class]: if not os.getenv('DDF_SHELL_MODE'): msg = "Override a lesson is an anti-pattern and will turn your test suite very hard to understand." @@ -250,12 +251,19 @@ def add_configuration(self, model_class, kwargs, name=None): def get_configuration(self, model_class, name=None): if name is None: name = self.DEFAULT_KEY + model_class = self._get_concrete_model(model_class) # copy is important because this dict will be updated every time in the algorithm. config = self.configs.get(model_class, {}) if name != self.DEFAULT_KEY and name not in config.keys(): raise InvalidConfigurationError('There is no lesson for model {} with the name "{}"'.format(get_unique_model_name(model_class), name)) return config.get(name, {}).copy() # default configuration never raises an error + def _get_concrete_model(self, model_class): + if hasattr(model_class, '_meta') and model_class._meta.proxy: + return model_class._meta.concrete_model or model_class + else: + return model_class + def clear(self): '''Remove all lessons of the library. Util for the DDF tests.''' self.configs = {} diff --git a/django_dynamic_fixture/models_test.py b/django_dynamic_fixture/models_test.py index 17d1dde..b36b618 100644 --- a/django_dynamic_fixture/models_test.py +++ b/django_dynamic_fixture/models_test.py @@ -352,6 +352,13 @@ class Meta: app_label = 'django_dynamic_fixture' +class ProxyModelForLibrary(ModelForLibrary): + class Meta: + proxy = True + verbose_name = 'Proxy Library' + app_label = 'django_dynamic_fixture' + + class ModelWithUniqueCharField(models.Model): text_unique = models.CharField(max_length=20, unique=True) diff --git a/django_dynamic_fixture/tests/test_ddf_teaching_and_lessons.py b/django_dynamic_fixture/tests/test_ddf_teaching_and_lessons.py index d15639b..95d7961 100644 --- a/django_dynamic_fixture/tests/test_ddf_teaching_and_lessons.py +++ b/django_dynamic_fixture/tests/test_ddf_teaching_and_lessons.py @@ -65,6 +65,24 @@ def test_it_must_use_lessons_for_internal_dependencies(self): assert instance.integer == 1000 assert instance.foreignkey.integer == 1001 + def test_it_uses_lessons_for_base_model_when_creating_a_proxy_model(self): + self.ddf.teach(ModelForLibrary, integer=123) + instance = self.ddf.get(ProxyModelForLibrary) + assert instance.__class__ is ProxyModelForLibrary + assert instance.integer == 123 + + def test_it_uses_lessons_for_proxy_models_when_creating_the_base_model(self): + self.ddf.teach(ProxyModelForLibrary, integer=456) + instance = self.ddf.get(ModelForLibrary) + assert instance.__class__ is ModelForLibrary + assert instance.integer == 456 + + def test_it_uses_lessons_for_proxy_models_when_creating_the_proxy_model(self): + self.ddf.teach(ProxyModelForLibrary, integer=789) + instance = self.ddf.get(ProxyModelForLibrary) + assert instance.__class__ is ProxyModelForLibrary + assert instance.integer == 789 + # Not implemented yet # def test_teaching_must_store_ddf_configs_too(self): # self.ddf.teach(ModelForLibrary, fill_nullable_fields=False)