Skip to content

Commit

Permalink
Merge pull request #112 from paulocheque/cannot-save-polymorphic
Browse files Browse the repository at this point in the history
Django-Polymorphic support
  • Loading branch information
paulocheque committed Jan 5, 2020
2 parents d6e393f + ecc8362 commit af8a144
Show file tree
Hide file tree
Showing 7 changed files with 83 additions and 10 deletions.
10 changes: 9 additions & 1 deletion django_dynamic_fixture/ddf.py
Original file line number Diff line number Diff line change
Expand Up @@ -413,7 +413,7 @@ def set_data_for_a_field(self, model_class, __instance, __field, persist_depende
if is_relationship_field(__field):
# Handle AttributeError for compatibility with django-polymorphic
# https://github.com/paulocheque/django-dynamic-fixture/issues/88
field_value = data.id if isinstance(e, AttributeError) else data
field_value = data.id if data and isinstance(e, AttributeError) else data
setattr(__instance, "%s_id" % __field.name, field_value) # Model.field = data
else:
six.reraise(*sys.exc_info())
Expand Down Expand Up @@ -478,9 +478,17 @@ def new(self, model_class, lesson=None, persist_dependencies=True, **kwargs):
instance = model_class()
if not is_model_class(instance):
raise InvalidModelError(get_unique_model_name(model_class))
try:
# https://github.com/paulocheque/django-dynamic-fixture/pull/112
from polymorphic import PolymorphicModel
is_polymorphic = isinstance(instance, PolymorphicModel)
except ImportError:
# Django-polymorphic is not installed so the model can't be polymorphic.
is_polymorphic = False
for field in get_fields_from_model(model_class):
if is_key_field(field) and field.name not in configuration: continue
if field.name not in self.kwargs and self._is_ignored_field(field.name): continue
if is_polymorphic and (field.name == 'polymorphic_ctype' or field.primary_key): continue
self.set_data_for_a_field(model_class, instance, field, persist_dependencies=persist_dependencies, **configuration)
number_of_pending_fields = len(self.pending_fields)
# For Copier fixtures: dealing with pending fields that need to receive values of another fields.
Expand Down
6 changes: 5 additions & 1 deletion django_dynamic_fixture/django_helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,11 @@ def print_field_values_of_a_model(model_instance):
else:
print('\n:: Model %s (%s)' % (get_unique_model_name(model_instance.__class__), model_instance.pk))
for field in get_fields_from_model(model_instance.__class__):
print('%s: %s' % (field.name, getattr(model_instance, field.name)))
try:
value = getattr(model_instance, field.name)
except Exception as e:
value = repr(e)
print('%s: %s' % (field.name, value))
if model_instance.pk is not None:
for field in get_many_to_many_fields_from_model(model_instance.__class__):
print('%s: %s' % (field.name, getattr(model_instance, field.name).all()))
Expand Down
26 changes: 24 additions & 2 deletions django_dynamic_fixture/models_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -437,7 +437,7 @@ class ModelForPlugins1(models.Model):
class Meta:
app_label = 'django_dynamic_fixture'
except ImportError:
pass
print('Library `jsonfield` not installed. Skipping.')


try:
Expand All @@ -447,4 +447,26 @@ class ModelForPlugins2(models.Model):
class Meta:
app_label = 'django_dynamic_fixture'
except ImportError:
pass
print('Library `django-json-field` not installed. Skipping.')


try:
from polymorphic.models import PolymorphicModel
class ModelPolymorphic(PolymorphicModel):
class Meta:
verbose_name = 'Polymorphic Model'


class ModelPolymorphic2(ModelPolymorphic):
class Meta:
verbose_name = 'Polymorphic Model 2'


class ModelPolymorphic3(ModelPolymorphic):
class CannotSave(Exception):
pass

def save(self):
raise self.CannotSave
except ImportError:
print('Library `django_polymorphic` not installed. Skipping.')
25 changes: 25 additions & 0 deletions django_dynamic_fixture/tests/test_ddf_custom_models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# -*- coding: utf-8 -*-
from django.test import TestCase
import pytest

from django_dynamic_fixture.models_test import *
from django_dynamic_fixture.ddf import *
from django_dynamic_fixture import G

try:
from polymorphic.models import PolymorphicModel

class PolymorphicModelTest(TestCase):
def test_create_polymorphic_model_and_retrieve(self):
p = G(ModelPolymorphic)
assert list(ModelPolymorphic.objects.all()) == [p]

def test_create_polymorphic_model_2_and_retrieve(self):
p = G(ModelPolymorphic2)
assert list(ModelPolymorphic2.objects.all()) == [p]

def test_cannot_save(self):
with self.assertRaises(BadDataError):
G(ModelPolymorphic3)
except ImportError:
pass
3 changes: 2 additions & 1 deletion requirements-dev.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ pytest-xdist # Run tests in parallel
pytest-cov
tox # For the CI

psycopg2==2.8.4 # For tests with Postgres fields
psycopg2-binary
#psycopg2==2.8.4 # For tests with Postgres fields
#or psycopg2cffi==2.7.5 # For pypy

coveralls
Expand Down
15 changes: 10 additions & 5 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,15 +1,20 @@
# Python2/3 compatibility
six

# For the Nose plugin
nose>=1.3
django-nose>=1.4.5
nose-progressive>=1.5

six

jsonfield
django-json-field

# Database Drivers
#mysql-python
#psycopg2 # not pypy compatible
#psycopg2cffi # pypy2+ compatible

# DjangoGEO
geopy

# 3rd party libraries
jsonfield
django-json-field
django-polymorphic
8 changes: 8 additions & 0 deletions settings_ddf.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,15 @@
'queries',
'django_nose',
'django_dynamic_fixture',
'django.contrib.contenttypes',
)
try:
import polymorphic
INSTALLED_APPS += ('polymorphic',)
except ImportError:
pass



TEST_RUNNER = 'django_nose.NoseTestSuiteRunner'
NOSE_PLUGINS = ['queries.Queries', 'ddf_setup.DDFSetup']
Expand Down

0 comments on commit af8a144

Please sign in to comment.