Skip to content

Commit

Permalink
Add support for Django 1.10, drop django 1.7.
Browse files Browse the repository at this point in the history
Fixes #31, thanks @cdobbyn for report and partial fixes.
  • Loading branch information
craigds committed Dec 15, 2016
1 parent 66727af commit 7b50566
Show file tree
Hide file tree
Showing 4 changed files with 17 additions and 19 deletions.
1 change: 1 addition & 0 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ def read_relative_file(filename):
'Programming Language :: Python :: 3',
'Programming Language :: Python :: 3.3',
'Programming Language :: Python :: 3.4',
'Programming Language :: Python :: 3.5',
'Topic :: Utilities'
],
)
8 changes: 5 additions & 3 deletions tox.ini
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@

[tox]
envlist = {py27,py33,py34,pypy}-{dj17,dj18,dj19}
envlist = {py27,py33,py34,py35,pypy}-{dj18}
{py27,py34,py35,pypy}-{dj19,dj110}

toxworkdir = {homedir}/.tox-django-typed-models

Expand All @@ -14,10 +15,11 @@ basepython =
py27: python2.7
py33: python3.3
py34: python3.4
py35: python3.5
pypy: pypy
deps =
pyyaml
coveralls
dj17: Django>=1.7,<1.8
dj18: Django>=1.8,<1.9
dj19: Django>=1.9a1,<1.10
dj19: Django>=1.9,<1.10
dj110: Django>=1.10,<1.11
24 changes: 10 additions & 14 deletions typedmodels/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
from django.db import models
from django.db.models.base import ModelBase
from django.db.models.fields import Field
from django.db.models.query_utils import DeferredAttribute, deferred_class_factory
from django.utils.encoding import smart_text
from django.utils.six import with_metaclass

Expand Down Expand Up @@ -179,7 +178,9 @@ class Manager(TypedModelManager, cls._default_manager.__class__):
manager = cls._default_manager
if manager is not None:
cls.add_to_class('objects', manager)
cls._default_manager = cls.objects
if django.VERSION < (1, 10):
# _default_manager became readonly in django 1.10. luckily we don't actually need it.
cls._default_manager = cls.objects

# add a get_type_classes classmethod to allow fetching of all the subclasses (useful for admin)

Expand Down Expand Up @@ -297,15 +298,6 @@ def _fill_m2m_cache(self):
del cls._meta.__dict__['fields']


def get_deferred_class_for_instance(instance, desired_class):
"""
Returns a deferred class (as used by instances in a .defer() queryset).
"""
original_cls = instance.__class__
attrs = [k for (k, v) in original_cls.__dict__.items() if isinstance(v, DeferredAttribute)]
return deferred_class_factory(desired_class, attrs)


class TypedModel(with_metaclass(TypedModelMetaclass, models.Model)):
'''
This class contains the functionality required to auto-downcast a model based
Expand Down Expand Up @@ -339,6 +331,7 @@ class Feline(Animal):
def say_something(self):
return "meoww"
'''
objects = TypedModelManager()

type = models.CharField(choices=(), max_length=255, null=False, blank=False, db_index=True)

Expand Down Expand Up @@ -407,9 +400,12 @@ def recast(self, typ=None):
current_cls = self.__class__

if current_cls != correct_cls:
if self._deferred:
# create a new deferred class based on correct_cls instead of current_cls
correct_cls = get_deferred_class_for_instance(self, correct_cls)
if django.VERSION < (1, 10) and self._deferred:
# older django used a special class created on the fly for deferred model instances.
# So we need to create a new deferred class based on correct_cls instead of current_cls
from django.db.models.query_utils import DeferredAttribute, deferred_class_factory
attrs = [k for (k, v) in current_cls.__dict__.items() if isinstance(v, DeferredAttribute)]
correct_cls = deferred_class_factory(correct_cls, attrs)
self.__class__ = correct_cls

def save(self, *args, **kwargs):
Expand Down
3 changes: 1 addition & 2 deletions typedmodels/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -165,8 +165,7 @@ def test_queryset_defer(self):
for o in objs:
print(o)
self.assertIsInstance(o, AbstractVegetable)
self.assertTrue(o._deferred)
self.assertIsInstance(o.__class__.__dict__['yumness'], DeferredAttribute)
self.assertSetEqual(o.get_deferred_fields(), {'yumness'})
# does a query, since this field was deferred
self.assertIsInstance(o.yumness, float)

Expand Down

0 comments on commit 7b50566

Please sign in to comment.