[Python-modules-commits] [django-model-utils] 01/03: Import django-model-utils_2.4.orig.tar.gz
Brian May
bam at moszumanska.debian.org
Wed Dec 2 22:03:13 UTC 2015
This is an automated email from the git hooks/post-receive script.
bam pushed a commit to branch master
in repository django-model-utils.
commit c0b30b27ddf45636f54c8dde126a6fc0a8a8ddb9
Author: Brian May <bam at debian.org>
Date: Thu Dec 3 08:56:29 2015 +1100
Import django-model-utils_2.4.orig.tar.gz
---
.travis.yml | 2 +
AUTHORS.rst | 2 +
CHANGES.rst | 5 ++
model_utils/__init__.py | 2 +-
model_utils/fields.py | 5 ++
model_utils/managers.py | 94 ++------------------------------
model_utils/models.py | 8 ++-
model_utils/tests/fields.py | 61 +++++++++++++--------
model_utils/tests/models.py | 76 ++------------------------
model_utils/tests/tests.py | 128 ++++----------------------------------------
setup.py | 1 +
tox.ini | 8 +--
12 files changed, 83 insertions(+), 309 deletions(-)
diff --git a/.travis.yml b/.travis.yml
index b24d579..b23f12e 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -12,6 +12,7 @@ env:
- TOXENV=py27-django16
- TOXENV=py27-django17
- TOXENV=py27-django18
+ - TOXENV=py27-django19
- TOXENV=py27-django_trunk
- TOXENV=py32-django15
- TOXENV=py32-django16
@@ -25,6 +26,7 @@ env:
- TOXENV=py33-django_trunk
- TOXENV=py34-django17
- TOXENV=py34-django18
+ - TOXENV=py34-django19
- TOXENV=py34-django_trunk
install:
diff --git a/AUTHORS.rst b/AUTHORS.rst
index b25a3cf..1776b2b 100644
--- a/AUTHORS.rst
+++ b/AUTHORS.rst
@@ -16,6 +16,7 @@ Gregor Müllegger <gregor at muellegger.de>
ivirabyan
James Oakley <jfunk at funktronics.ca>
Jannis Leidel <jannis at leidel.info>
+Jarek Glowacki <github.com/jarekwg>
Javier García Sogo <jgsogo at gmail.com>
Jeff Elmore <jeffelmore.org>
Keryn Knight <kerynknight.com>
@@ -34,4 +35,5 @@ sayane
Tony Aldridge <zaragopha at hotmail.com>
Travis Swicegood <travis at domain51.com>
Trey Hunner <trey at treyhunner.com>
+Karl Wan Nan Wo <karl.wnw at gmail.com>
zyegfryed
diff --git a/CHANGES.rst b/CHANGES.rst
index 1fc9a62..0c450d7 100644
--- a/CHANGES.rst
+++ b/CHANGES.rst
@@ -1,6 +1,11 @@
CHANGES
=======
+2.4 (2015-12-03)
+----------------
+
+* Add support for Django 1.9. Drop support for Django 1.6 and earlier.
+
2.3.1 (2015-07-20)
------------------
diff --git a/model_utils/__init__.py b/model_utils/__init__.py
index 272f4ca..782fa33 100644
--- a/model_utils/__init__.py
+++ b/model_utils/__init__.py
@@ -1,4 +1,4 @@
from .choices import Choices
from .tracker import FieldTracker, ModelTracker
-__version__ = '2.3.1'
+__version__ = '2.4'
diff --git a/model_utils/fields.py b/model_utils/fields.py
index 74c44b2..805c707 100644
--- a/model_utils/fields.py
+++ b/model_utils/fields.py
@@ -1,5 +1,6 @@
from __future__ import unicode_literals
+import django
from django.db import models
from django.conf import settings
from django.utils.encoding import python_2_unicode_compatible
@@ -59,6 +60,8 @@ class StatusField(models.CharField):
"To use StatusField, the model '%s' must have a %s choices class attribute." \
% (sender.__name__, self.choices_name)
self._choices = getattr(sender, self.choices_name)
+ if django.VERSION >= (1, 9, 0):
+ self.choices = self._choices
if not self.has_default():
self.default = tuple(getattr(sender, self.choices_name))[0][0] # set first as default
@@ -68,6 +71,8 @@ class StatusField(models.CharField):
# the STATUS class attr being available), but we need to set some dummy
# choices now so the super method will add the get_FOO_display method
self._choices = [(0, 'dummy')]
+ if django.VERSION >= (1, 9, 0):
+ self.choices = self._choices
super(StatusField, self).contribute_to_class(cls, name)
def deconstruct(self):
diff --git a/model_utils/managers.py b/model_utils/managers.py
index b6496ba..9392e69 100644
--- a/model_utils/managers.py
+++ b/model_utils/managers.py
@@ -57,8 +57,10 @@ class InheritanceQuerySetMixin(object):
for name in ['subclasses', '_annotated']:
if hasattr(self, name):
kwargs[name] = getattr(self, name)
- return super(InheritanceQuerySetMixin, self)._clone(
- klass, setup, **kwargs)
+ if django.VERSION < (1, 9):
+ kwargs['klass'] = klass
+ kwargs['setup'] = setup
+ return super(InheritanceQuerySetMixin, self)._clone(**kwargs)
def annotate(self, *args, **kwargs):
qset = super(InheritanceQuerySetMixin, self).annotate(*args, **kwargs)
@@ -224,91 +226,3 @@ class QueryManagerMixin(object):
class QueryManager(QueryManagerMixin, models.Manager):
pass
-
-
-class PassThroughManagerMixin(object):
- """
- A mixin that enables you to call custom QuerySet methods from your manager.
- """
-
- # pickling causes recursion errors
- _deny_methods = ['__getstate__', '__setstate__', '__getinitargs__',
- '__getnewargs__', '__copy__', '__deepcopy__', '_db',
- '__slots__']
-
- def __init__(self, queryset_cls=None):
- self._queryset_cls = queryset_cls
- super(PassThroughManagerMixin, self).__init__()
-
- def __getattr__(self, name):
- if name in self._deny_methods:
- raise AttributeError(name)
- if django.VERSION < (1, 6, 0):
- return getattr(self.get_query_set(), name)
- return getattr(self.get_queryset(), name)
-
- def __dir__(self):
- """
- Allow introspection via dir() and ipythonesque tab-discovery.
-
- We do dir(type(self)) because to do dir(self) would be a recursion
- error.
- We call dir(self.get_query_set()) because it is possible that the
- queryset returned by get_query_set() is interesting, even if
- self._queryset_cls is None.
- """
- my_values = frozenset(dir(type(self)))
- my_values |= frozenset(dir(self.get_query_set()))
- return list(my_values)
-
- def get_queryset(self):
- try:
- qs = super(PassThroughManagerMixin, self).get_queryset()
- except AttributeError:
- qs = super(PassThroughManagerMixin, self).get_query_set()
- if self._queryset_cls is not None:
- qs = qs._clone(klass=self._queryset_cls)
- return qs
-
- get_query_set = get_queryset
-
- @classmethod
- def for_queryset_class(cls, queryset_cls):
- return create_pass_through_manager_for_queryset_class(
- cls, queryset_cls)
-
-
-class PassThroughManager(PassThroughManagerMixin, models.Manager):
- """
- Inherit from this Manager to enable you to call any methods from your
- custom QuerySet class from your manager. Simply define your QuerySet
- class, and return an instance of it from your manager's `get_queryset`
- method.
-
- Alternately, if you don't need any extra methods on your manager that
- aren't on your QuerySet, then just pass your QuerySet class to the
- ``for_queryset_class`` class method.
-
- class PostQuerySet(QuerySet):
- def enabled(self):
- return self.filter(disabled=False)
-
- class Post(models.Model):
- objects = PassThroughManager.for_queryset_class(PostQuerySet)()
-
- """
- pass
-
-
-def create_pass_through_manager_for_queryset_class(base, queryset_cls):
- class _PassThroughManager(base):
- def __init__(self, *args, **kwargs):
- return super(_PassThroughManager, self).__init__(*args, **kwargs)
-
- def get_queryset(self):
- qs = super(_PassThroughManager, self).get_queryset()
- return qs._clone(klass=queryset_cls)
-
- get_query_set = get_queryset
-
- return _PassThroughManager
diff --git a/model_utils/models.py b/model_utils/models.py
index f343dfb..3db4073 100644
--- a/model_utils/models.py
+++ b/model_utils/models.py
@@ -1,10 +1,14 @@
from __future__ import unicode_literals
+import django
from django.db import models
from django.utils.translation import ugettext_lazy as _
-from django.db.models.fields import FieldDoesNotExist
from django.core.exceptions import ImproperlyConfigured
-from django.utils.timezone import now
+if django.VERSION >= (1, 9, 0):
+ from django.db.models.functions import Now
+ now = Now()
+else:
+ from django.utils.timezone import now
from model_utils.managers import QueryManager
from model_utils.fields import AutoCreatedField, AutoLastModifiedField, \
diff --git a/model_utils/tests/fields.py b/model_utils/tests/fields.py
index 3f1503a..7c29aa4 100644
--- a/model_utils/tests/fields.py
+++ b/model_utils/tests/fields.py
@@ -1,26 +1,43 @@
+import django
from django.db import models
from django.utils.six import with_metaclass, string_types
-class MutableField(with_metaclass(models.SubfieldBase, models.TextField)):
-
- def to_python(self, value):
- if value == '':
- return None
-
- try:
- if isinstance(value, string_types):
- return [int(i) for i in value.split(',')]
- except ValueError:
- pass
-
- return value
-
- def get_db_prep_save(self, value, connection):
- if value is None:
- return ''
-
- if isinstance(value, list):
- value = ','.join((str(i) for i in value))
-
- return super(MutableField, self).get_db_prep_save(value, connection)
+def mutable_from_db(value):
+ if value == '':
+ return None
+ try:
+ if isinstance(value, string_types):
+ return [int(i) for i in value.split(',')]
+ except ValueError:
+ pass
+ return value
+
+
+def mutable_to_db(value):
+ if value is None:
+ return ''
+ if isinstance(value, list):
+ value = ','.join((str(i) for i in value))
+ return str(value)
+
+
+if django.VERSION >= (1, 9, 0):
+ class MutableField(models.TextField):
+ def to_python(self, value):
+ return mutable_from_db(value)
+
+ def from_db_value(self, value, expression, connection, context):
+ return mutable_from_db(value)
+
+ def get_db_prep_save(self, value, connection):
+ value = super(MutableField, self).get_db_prep_save(value, connection)
+ return mutable_to_db(value)
+else:
+ class MutableField(with_metaclass(models.SubfieldBase, models.TextField)):
+ def to_python(self, value):
+ return mutable_from_db(value)
+
+ def get_db_prep_save(self, value, connection):
+ value = mutable_to_db(value)
+ return super(MutableField, self).get_db_prep_save(value, connection)
diff --git a/model_utils/tests/models.py b/model_utils/tests/models.py
index ea46d0f..6b82541 100644
--- a/model_utils/tests/models.py
+++ b/model_utils/tests/models.py
@@ -6,7 +6,7 @@ from django.utils.translation import ugettext_lazy as _
from model_utils.models import TimeStampedModel, StatusModel, TimeFramedModel
from model_utils.tracker import FieldTracker, ModelTracker
-from model_utils.managers import QueryManager, InheritanceManager, PassThroughManager
+from model_utils.managers import QueryManager, InheritanceManager
from model_utils.fields import SplitField, MonitorField, StatusField
from model_utils.tests.fields import MutableField
from model_utils import Choices
@@ -201,80 +201,10 @@ class FeaturedManager(models.Manager):
get_query_set = get_queryset
-class DudeQuerySet(models.query.QuerySet):
- def abiding(self):
- return self.filter(abides=True)
-
- def rug_positive(self):
- return self.filter(has_rug=True)
-
- def rug_negative(self):
- return self.filter(has_rug=False)
-
- def by_name(self, name):
- return self.filter(name__iexact=name)
-
-
-
-class AbidingManager(PassThroughManager):
- def get_queryset(self):
- return DudeQuerySet(self.model).abiding()
-
- get_query_set = get_queryset
-
- def get_stats(self):
- return {
- "abiding_count": self.count(),
- "rug_count": self.rug_positive().count(),
- }
-
-
-
-class Dude(models.Model):
- abides = models.BooleanField(default=True)
- name = models.CharField(max_length=20)
- has_rug = models.BooleanField(default=False)
-
- objects = PassThroughManager(DudeQuerySet)
- abiders = AbidingManager()
-
-
-class Car(models.Model):
- name = models.CharField(max_length=20)
- owner = models.ForeignKey(Dude, related_name='cars_owned')
-
- objects = PassThroughManager(DudeQuerySet)
-
-
-class SpotManager(PassThroughManager):
- def get_queryset(self):
- return super(SpotManager, self).get_queryset().filter(secret=False)
-
- get_query_set = get_queryset
-
-
-class SpotQuerySet(models.query.QuerySet):
- def closed(self):
- return self.filter(closed=True)
-
- def secured(self):
- return self.filter(secure=True)
-
-
-class Spot(models.Model):
- name = models.CharField(max_length=20)
- secure = models.BooleanField(default=True)
- closed = models.BooleanField(default=False)
- secret = models.BooleanField(default=False)
- owner = models.ForeignKey(Dude, related_name='spots_owned')
-
- objects = SpotManager.for_queryset_class(SpotQuerySet)()
-
-
class Tracked(models.Model):
name = models.CharField(max_length=20)
number = models.IntegerField()
- mutable = MutableField()
+ mutable = MutableField(default=None)
tracker = FieldTracker()
@@ -319,7 +249,7 @@ class InheritedTracked(Tracked):
class ModelTracked(models.Model):
name = models.CharField(max_length=20)
number = models.IntegerField()
- mutable = MutableField()
+ mutable = MutableField(default=None)
tracker = ModelTracker()
diff --git a/model_utils/tests/tests.py b/model_utils/tests/tests.py
index bbacfd1..d32bf86 100644
--- a/model_utils/tests/tests.py
+++ b/model_utils/tests/tests.py
@@ -1,7 +1,6 @@
from __future__ import unicode_literals
from datetime import datetime, timedelta
-import pickle
try:
from unittest import skipUnless
except ImportError: # Python 2.6
@@ -25,7 +24,7 @@ from model_utils.tests.models import (
InheritanceManagerTestParent, InheritanceManagerTestChild1,
InheritanceManagerTestChild2, TimeStamp, Post, Article, Status,
StatusPlainTuple, TimeFrame, Monitored, MonitorWhen, MonitorWhenEmpty, StatusManagerAdded,
- TimeFrameManagerAdded, Dude, SplitFieldAbstractParent, Car, Spot,
+ TimeFrameManagerAdded, SplitFieldAbstractParent,
ModelTracked, ModelTrackedFK, ModelTrackedNotDefault, ModelTrackedMultiple, InheritedModelTracked,
Tracked, TrackedFK, TrackedNotDefault, TrackedNonFieldAttr, TrackedMultiple,
InheritedTracked, StatusFieldDefaultFilled, StatusFieldDefaultNotFilled,
@@ -764,6 +763,11 @@ class InheritanceManagerTests(TestCase):
set(expected_related_names))
+ def test_filter_on_values_queryset(self):
+ queryset = InheritanceManagerTestChild1.objects.values('id').filter(pk=self.child1.pk)
+ self.assertEqual(list(queryset), [{'id': self.child1.pk}])
+
+
class InheritanceManagerUsingModelsTests(TestCase):
def setUp(self):
@@ -872,11 +876,10 @@ class InheritanceManagerUsingModelsTests(TestCase):
"""
Confirming that giving a stupid model doesn't work.
"""
- from django.contrib.auth.models import User
regex = '^.+? is not a subclass of .+$'
with self.assertRaisesRegexp(ValueError, regex):
InheritanceManagerTestParent.objects.select_subclasses(
- User).order_by('pk')
+ TimeFrame).order_by('pk')
@@ -1206,115 +1209,6 @@ class SouthFreezingTests(TestCase):
self.assertEqual(kwargs['no_check_for_status'], 'True')
-
-class PassThroughManagerTests(TestCase):
- def setUp(self):
- Dude.objects.create(name='The Dude', abides=True, has_rug=False)
- Dude.objects.create(name='His Dudeness', abides=False, has_rug=True)
- Dude.objects.create(name='Duder', abides=False, has_rug=False)
- Dude.objects.create(name='El Duderino', abides=True, has_rug=True)
-
-
- def test_chaining(self):
- self.assertEqual(Dude.objects.by_name('Duder').count(), 1)
- self.assertEqual(Dude.objects.all().by_name('Duder').count(), 1)
- self.assertEqual(Dude.abiders.rug_positive().count(), 1)
- self.assertEqual(Dude.abiders.all().rug_positive().count(), 1)
-
-
- def test_manager_only_methods(self):
- stats = Dude.abiders.get_stats()
- self.assertEqual(stats['rug_count'], 1)
- with self.assertRaises(AttributeError):
- Dude.abiders.all().get_stats()
-
-
- def test_queryset_pickling(self):
- qs = Dude.objects.all()
- saltyqs = pickle.dumps(qs)
- unqs = pickle.loads(saltyqs)
- self.assertEqual(unqs.by_name('The Dude').count(), 1)
-
-
- def test_queryset_not_available_on_related_manager(self):
- dude = Dude.objects.by_name('Duder').get()
- Car.objects.create(name='Ford', owner=dude)
- self.assertFalse(hasattr(dude.cars_owned, 'by_name'))
-
-
- def test_using_dir(self):
- # make sure introspecing via dir() doesn't actually cause queries,
- # just as a sanity check.
- with self.assertNumQueries(0):
- querysets_to_dir = (
- Dude.objects,
- Dude.objects.by_name('Duder'),
- Dude.objects.all().by_name('Duder'),
- Dude.abiders,
- Dude.abiders.rug_positive(),
- Dude.abiders.all().rug_positive()
- )
- for qs in querysets_to_dir:
- self.assertTrue('by_name' in dir(qs))
- self.assertTrue('abiding' in dir(qs))
- self.assertTrue('rug_positive' in dir(qs))
- self.assertTrue('rug_negative' in dir(qs))
- # some standard qs methods
- self.assertTrue('count' in dir(qs))
- self.assertTrue('order_by' in dir(qs))
- self.assertTrue('select_related' in dir(qs))
- # make sure it's been de-duplicated
- self.assertEqual(1, dir(qs).count('distinct'))
-
- # manager only method.
- self.assertTrue('get_stats' in dir(Dude.abiders))
- # manager only method shouldn't appear on the non AbidingManager
- self.assertFalse('get_stats' in dir(Dude.objects))
- # standard manager methods
- self.assertTrue('get_query_set' in dir(Dude.abiders))
- self.assertTrue('contribute_to_class' in dir(Dude.abiders))
-
-
-
-class CreatePassThroughManagerTests(TestCase):
- def setUp(self):
- self.dude = Dude.objects.create(name='El Duderino')
- self.other_dude = Dude.objects.create(name='Das Dude')
-
- def test_reverse_manager(self):
- Spot.objects.create(
- name='The Crib', owner=self.dude, closed=True, secure=True,
- secret=False)
- self.assertEqual(self.dude.spots_owned.closed().count(), 1)
- Spot.objects.create(
- name='The Crux', owner=self.other_dude, closed=True, secure=True,
- secret=False
- )
- self.assertEqual(self.dude.spots_owned.closed().all().count(), 1)
- self.assertEqual(self.dude.spots_owned.closed().count(), 1)
-
- def test_related_queryset_pickling(self):
- Spot.objects.create(
- name='The Crib', owner=self.dude, closed=True, secure=True,
- secret=False)
- qs = self.dude.spots_owned.closed()
- pickled_qs = pickle.dumps(qs)
- unpickled_qs = pickle.loads(pickled_qs)
- self.assertEqual(unpickled_qs.secured().count(), 1)
-
- def test_related_queryset_superclass_method(self):
- Spot.objects.create(
- name='The Crib', owner=self.dude, closed=True, secure=True,
- secret=False)
- Spot.objects.create(
- name='The Secret Crib', owner=self.dude, closed=False, secure=True,
- secret=True)
- self.assertEqual(self.dude.spots_owned.count(), 1)
-
- def test_related_manager_create(self):
- self.dude.spots_owned.create(name='The Crib', closed=True, secure=True)
-
-
class FieldTrackerTestCase(TestCase):
tracker = None
@@ -1502,15 +1396,13 @@ class FieldTrackerTests(FieldTrackerTestCase, FieldTrackerCommonTests):
class FieldTrackerMultipleInstancesTests(TestCase):
def test_with_deferred_fields_access_multiple(self):
- instances = [
- Tracked.objects.create(pk=1, name='foo', number=1),
- Tracked.objects.create(pk=2, name='bar', number=2)
- ]
+ Tracked.objects.create(pk=1, name='foo', number=1)
+ Tracked.objects.create(pk=2, name='bar', number=2)
queryset = Tracked.objects.only('id')
for instance in queryset:
- name = instance.name
+ instance.name
class FieldTrackedModelCustomTests(FieldTrackerTestCase,
diff --git a/setup.py b/setup.py
index a1b49b6..feb5ffc 100644
--- a/setup.py
+++ b/setup.py
@@ -35,6 +35,7 @@ setup(
'Programming Language :: Python :: 3',
'Programming Language :: Python :: 3.2',
'Programming Language :: Python :: 3.3',
+ 'Programming Language :: Python :: 3.4',
'Framework :: Django',
],
zip_safe=False,
diff --git a/tox.ini b/tox.ini
index 5255cf5..40aa033 100644
--- a/tox.ini
+++ b/tox.ini
@@ -3,7 +3,8 @@ envlist =
py26-django{14,15,16},
py27-django14, py27-django15_nosouth,
py{27,32,33}-django{15,16,17,18,_trunk},
- py34-django{17,18,_trunk},
+ py27-django19,
+ py34-django{17,18,19,_trunk},
[testenv]
basepython =
@@ -18,8 +19,9 @@ deps =
django14: Django==1.4.18
django15{,_nosouth}: Django==1.5.12
django16: Django==1.6.10
- django17: Django==1.7.3
- django18: Django==1.8a1
+ django17: Django==1.7.7
+ django18: Django==1.8.5
+ django19: Django==1.9
django_trunk: https://github.com/django/django/tarball/master
django{14,15,16}: South==1.0.2
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/python-modules/packages/django-model-utils.git
More information about the Python-modules-commits
mailing list