[Python-modules-commits] [django-model-utils] 01/03: Import django-model-utils_2.5.2.orig.tar.gz
Brian May
bam at moszumanska.debian.org
Fri Aug 12 04:52:22 UTC 2016
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 3896a3775fa50d001bf7fe4104550e3055fb2cc0
Author: Brian May <bam at debian.org>
Date: Fri Aug 12 14:48:49 2016 +1000
Import django-model-utils_2.5.2.orig.tar.gz
---
.travis.yml | 18 ++++++++-------
AUTHORS.rst | 2 ++
CHANGES.rst | 35 +++++++++++++++++++++++++++--
CONTRIBUTING.rst | 15 +++++++------
MANIFEST.in | 3 ++-
README.rst | 26 +++++++++------------
TODO.rst | 4 ----
docs/managers.rst | 47 +++-----------------------------------
docs/utilities.rst | 2 +-
model_utils/__init__.py | 2 +-
model_utils/managers.py | 28 ++++++++++++++++++-----
model_utils/tests/models.py | 5 +++++
model_utils/tests/tests.py | 55 ++++++++++++++++++++++++++++++++++++++++++++-
model_utils/tracker.py | 6 ++---
requirements.txt | 3 +++
setup.py | 24 +++++++++++++-------
tox.ini | 23 ++++++++++---------
17 files changed, 186 insertions(+), 112 deletions(-)
diff --git a/.travis.yml b/.travis.yml
index b23f12e..6ea0c92 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -6,6 +6,7 @@ env:
- TOXENV=py26-django14
- TOXENV=py26-django15
- TOXENV=py26-django16
+ - TOXENV=py27-django110
- TOXENV=py27-django14
- TOXENV=py27-django15
- TOXENV=py27-django15_nosouth
@@ -14,20 +15,19 @@ env:
- TOXENV=py27-django18
- TOXENV=py27-django19
- TOXENV=py27-django_trunk
- - TOXENV=py32-django15
- - TOXENV=py32-django16
- - TOXENV=py32-django17
- - TOXENV=py32-django18
- - TOXENV=py32-django_trunk
- TOXENV=py33-django15
- TOXENV=py33-django16
- TOXENV=py33-django17
- TOXENV=py33-django18
- - TOXENV=py33-django_trunk
+ - TOXENV=py34-django110
- TOXENV=py34-django17
- TOXENV=py34-django18
- TOXENV=py34-django19
- TOXENV=py34-django_trunk
+ - TOXENV=py35-django110
+ - TOXENV=py35-django18
+ - TOXENV=py35-django19
+ - TOXENV=py35-django_trunk
install:
- pip install --upgrade pip setuptools tox virtualenv coveralls
@@ -37,9 +37,11 @@ script:
matrix:
allow_failures:
+ - env: TOXENV=py27-django110
+ - env: TOXENV=py34-django110
+ - env: TOXENV=py35-django110
- env: TOXENV=py27-django_trunk
- - env: TOXENV=py32-django_trunk
- - env: TOXENV=py33-django_trunk
- env: TOXENV=py34-django_trunk
+ - env: TOXENV=py35-django_trunk
after_success: coveralls
diff --git a/AUTHORS.rst b/AUTHORS.rst
index 1776b2b..668453e 100644
--- a/AUTHORS.rst
+++ b/AUTHORS.rst
@@ -2,6 +2,7 @@ ad-m <github.com/ad-m>
Alejandro Varas <alej0varas at gmail.com>
Alex Orange <crazycasta at gmail.com>
Andy Freeland <andy at andyfreeland.net>
+Artis Avotins <artis.avotins at gmail.com>
Bram Boogaard <b.boogaard at auto-interactive.nl>
Carl Meyer <carl at dirtcircle.com>
Curtis Maloney <curtis at tinbrain.net>
@@ -22,6 +23,7 @@ Jeff Elmore <jeffelmore.org>
Keryn Knight <kerynknight.com>
Matthew Schinckel <matt at schinckel.net>
Michael van Tellingen <michaelvantellingen at gmail.com>
+Mike Bryant <mike at mikebryant.me.uk>
Mikhail Silonov <silonov.pro>
Patryk Zawadzki <patrys at room-303.com>
Paul McLanahan <paul at mclanahan.net>
diff --git a/CHANGES.rst b/CHANGES.rst
index 0c450d7..fa0bd0e 100644
--- a/CHANGES.rst
+++ b/CHANGES.rst
@@ -1,10 +1,41 @@
CHANGES
=======
-2.4 (2015-12-03)
+2.5.2 (2016.08.09)
+------------------
+
+* Include `runtests.py` in sdist.
+
+
+2.5.1 (2016.08.03)
+------------------
+
+* Fix `InheritanceQuerySet` raising an `AttributeError` exception
+ under Django 1.9.
+
+* Django 1.10 support regressed with changes between pre-alpha and final
+ release; 1.10 currently not supported.
+
+
+2.5 (2016.04.18)
----------------
-* Add support for Django 1.9. Drop support for Django 1.6 and earlier.
+* Drop support for Python 3.2.
+
+* Add support for Django 1.10 pre-alpha.
+
+* Track foreign keys on parent models properly when a tracker
+ is defined on a child model. Fixes GH-214.
+
+
+2.4 (2015.12.03)
+----------------
+
+* Remove `PassThroughManager`. Use Django's built-in `QuerySet.as_manager()`
+ and/or `Manager.from_queryset()` utilities instead.
+
+* Add support for Django 1.9.
+
2.3.1 (2015-07-20)
------------------
diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst
index 6b2b848..10fbcca 100644
--- a/CONTRIBUTING.rst
+++ b/CONTRIBUTING.rst
@@ -1,26 +1,26 @@
Contributing
============
-Below is a list of tips for submitting issues and pull requests. These are
-suggestions and not requirements.
+Below is a list of tips for submitting issues and pull requests.
Submitting Issues
-----------------
-Issues are often easier to reproduce/resolve when they have:
+Issues are easier to reproduce/resolve when they have:
- A pull request with a failing test demonstrating the issue
- A code example that produces the issue consistently
- A traceback (when applicable)
+
Pull Requests
-------------
-When creating a pull request, try to:
+When creating a pull request:
-- Write tests if applicable
-- Note important changes in the `CHANGES`_ file
-- Update the documentation if needed
+- Write tests
+- Note user-facing changes in the `CHANGES`_ file
+- Update the documentation
- Add yourself to the `AUTHORS`_ file
- If you have added or changed translated strings, run ``make messages`` to
update the ``.po`` translation files, and update translations for any
@@ -47,6 +47,7 @@ After you finished editing add yourself to the list of translators.
If you have created a new translation, make sure to copy the header from one
of the existing translation files.
+
Testing
-------
diff --git a/MANIFEST.in b/MANIFEST.in
index 48f0ac9..351a82c 100644
--- a/MANIFEST.in
+++ b/MANIFEST.in
@@ -4,4 +4,5 @@ include LICENSE.txt
include MANIFEST.in
include README.rst
include TODO.rst
-locale/*/LC_MESSAGES/django.po
\ No newline at end of file
+recursive-include locale django.po
+include runtests.py
diff --git a/README.rst b/README.rst
index b7ddd73..001712f 100644
--- a/README.rst
+++ b/README.rst
@@ -11,35 +11,29 @@ django-model-utils
Django model mixins and utilities.
-``django-model-utils`` supports `Django`_ 1.4.10 and later on Python 2.6, 2.7,
-3.2, 3.3 and 3.4.
+``django-model-utils`` supports `Django`_ 1.4 through 1.9 (latest bugfix
+release in each series only) on Python 2.6 (through Django 1.6 only), 2.7, 3.3
+(through Django 1.8 only), 3.4 and 3.5.
.. _Django: http://www.djangoproject.com/
+This app is available on `PyPI`_.
-Getting Help
-============
+.. _PyPI: https://pypi.python.org/pypi/django-model-utils/
-Documentation for django-model-utils is available at https://django-model-utils.readthedocs.org/
-This app is available on `PyPI`_.
+Getting Help
+============
-.. _PyPI: https://pypi.python.org/pypi/django-model-utils/
+Documentation for django-model-utils is available at https://django-model-utils.readthedocs.io/
Contributing
============
Please file bugs and send pull requests to the `GitHub repository`_ and `issue
-tracker`_.
+tracker`_. See `CONTRIBUTING.rst`_ for details.
.. _GitHub repository: https://github.com/carljm/django-model-utils/
.. _issue tracker: https://github.com/carljm/django-model-utils/issues
-
-(Until January 2013 django-model-utils primary development was hosted at
-`BitBucket`_; the issue tracker there will remain open until all issues and
-pull requests tracked in it are closed, but all new issues should be filed at
-GitHub.)
-
-.. _BitBucket: https://bitbucket.org/carljm/django-model-utils/overview
-
+.. _CONTRIBUTING.rst: https://github.com/carljm/django-model-utils/blob/master/CONTRIBUTING.rst
diff --git a/TODO.rst b/TODO.rst
deleted file mode 100644
index 4218c78..0000000
--- a/TODO.rst
+++ /dev/null
@@ -1,4 +0,0 @@
-TODO
-====
-
-* Switch to proper test skips once Django 1.3 is minimum supported.
diff --git a/docs/managers.rst b/docs/managers.rst
index 0fb3144..2669a1c 100644
--- a/docs/managers.rst
+++ b/docs/managers.rst
@@ -128,50 +128,9 @@ not required).
PassThroughManager
------------------
-A common "gotcha" when defining methods on a custom manager class is that those
-same methods are not automatically also available on the QuerySets returned by
-that manager, so are not "chainable". This can be counterintuitive, as most of
-the public QuerySet API is mirrored on managers. It is possible to create a
-custom Manager that returns QuerySets that have the same additional methods,
-but this requires boilerplate code. The ``PassThroughManager`` class
-(`contributed by Paul McLanahan`_) removes this boilerplate.
-
-.. _contributed by Paul McLanahan: http://paulm.us/post/3717466639/passthroughmanager-for-django
-
-To use ``PassThroughManager``, rather than defining a custom manager with
-additional methods, define a custom ``QuerySet`` subclass with the additional
-methods you want, and pass that ``QuerySet`` subclass to the
-``PassThroughManager.for_queryset_class()`` class method. The returned
-``PassThroughManager`` subclass will always return instances of your custom
-``QuerySet``, and you can also call methods of your custom ``QuerySet``
-directly on the manager:
-
-.. code-block:: python
-
- from datetime import datetime
- from django.db import models
- from django.db.models.query import QuerySet
- from model_utils.managers import PassThroughManager
-
- class PostQuerySet(QuerySet):
- def by_author(self, user):
- return self.filter(user=user)
-
- def published(self):
- return self.filter(published__lte=datetime.now())
-
- def unpublished(self):
- return self.filter(published__gte=datetime.now())
-
-
- class Post(models.Model):
- user = models.ForeignKey(User)
- published = models.DateTimeField()
-
- objects = PassThroughManager.for_queryset_class(PostQuerySet)()
-
- Post.objects.published()
- Post.objects.by_author(user=request.user).unpublished()
+`PassThroughManager` was removed in django-model-utils 2.4. Use Django's
+built-in `QuerySet.as_manager()` and/or `Manager.from_queryset()` utilities
+instead.
Mixins
------
diff --git a/docs/utilities.rst b/docs/utilities.rst
index e8d22d2..44824f5 100644
--- a/docs/utilities.rst
+++ b/docs/utilities.rst
@@ -153,7 +153,7 @@ Returns ``None`` when the model instance isn't saved yet.
has_changed
~~~~~~~~~~~
-Returns ``True`` if the given field has changed since the last save:
+Returns ``True`` if the given field has changed since the last save. The ``has_changed`` method expects a single field:
.. code-block:: pycon
diff --git a/model_utils/__init__.py b/model_utils/__init__.py
index 782fa33..e42aa57 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.4'
+__version__ = '2.5.2'
diff --git a/model_utils/managers.py b/model_utils/managers.py
index 9392e69..4f06d2e 100644
--- a/model_utils/managers.py
+++ b/model_utils/managers.py
@@ -1,7 +1,7 @@
from __future__ import unicode_literals
import django
from django.db import models
-from django.db.models.fields.related import OneToOneField
+from django.db.models.fields.related import OneToOneField, OneToOneRel
from django.db.models.query import QuerySet
from django.core.exceptions import ObjectDoesNotExist
@@ -101,12 +101,20 @@ class InheritanceQuerySetMixin(object):
recursively, returning a `list` of strings representing the
relations for select_related
"""
+ if django.VERSION < (1, 8):
+ related_objects = model._meta.get_all_related_objects()
+ else:
+ related_objects = [
+ f for f in model._meta.get_fields()
+ if isinstance(f, OneToOneRel)]
+
rels = [
- rel for rel in model._meta.get_all_related_objects()
+ rel for rel in related_objects
if isinstance(rel.field, OneToOneField)
and issubclass(rel.field.model, model)
and model is not rel.field.model
]
+
subclasses = []
if levels:
levels -= 1
@@ -135,12 +143,16 @@ class InheritanceQuerySetMixin(object):
if levels:
levels -= 1
while parent_link is not None:
- ancestry.insert(0, parent_link.related.get_accessor_name())
+ if django.VERSION < (1, 8):
+ related = parent_link.related
+ else:
+ related = parent_link.rel
+ ancestry.insert(0, related.get_accessor_name())
if levels or levels is None:
if django.VERSION < (1, 8):
- parent_model = parent_link.related.parent_model
+ parent_model = related.parent_model
else:
- parent_model = parent_link.related.model
+ parent_model = related.model
parent_link = parent_model._meta.get_ancestor_link(
self.model)
else:
@@ -149,6 +161,12 @@ class InheritanceQuerySetMixin(object):
def _get_sub_obj_recurse(self, obj, s):
rel, _, s = s.partition(LOOKUP_SEP)
+
+ # Django 1.9: If a primitive type gets passed to this recursive function,
+ # return None as non-models are not part of inheritance.
+ if not isinstance(obj, models.Model):
+ return None
+
try:
node = getattr(obj, rel)
except ObjectDoesNotExist:
diff --git a/model_utils/tests/models.py b/model_utils/tests/models.py
index 6b82541..c77c034 100644
--- a/model_utils/tests/models.py
+++ b/model_utils/tests/models.py
@@ -246,6 +246,11 @@ class InheritedTracked(Tracked):
name2 = models.CharField(max_length=20)
+class InheritedTrackedFK(TrackedFK):
+ custom_tracker = FieldTracker(fields=['fk_id'])
+ custom_tracker_without_id = FieldTracker(fields=['fk'])
+
+
class ModelTracked(models.Model):
name = models.CharField(max_length=20)
number = models.IntegerField()
diff --git a/model_utils/tests/tests.py b/model_utils/tests/tests.py
index d32bf86..14b6329 100644
--- a/model_utils/tests/tests.py
+++ b/model_utils/tests/tests.py
@@ -26,7 +26,7 @@ from model_utils.tests.models import (
StatusPlainTuple, TimeFrame, Monitored, MonitorWhen, MonitorWhenEmpty, StatusManagerAdded,
TimeFrameManagerAdded, SplitFieldAbstractParent,
ModelTracked, ModelTrackedFK, ModelTrackedNotDefault, ModelTrackedMultiple, InheritedModelTracked,
- Tracked, TrackedFK, TrackedNotDefault, TrackedNonFieldAttr, TrackedMultiple,
+ Tracked, TrackedFK, InheritedTrackedFK, TrackedNotDefault, TrackedNonFieldAttr, TrackedMultiple,
InheritedTracked, StatusFieldDefaultFilled, StatusFieldDefaultNotFilled,
InheritanceManagerTestChild3, StatusFieldChoicesName)
@@ -768,6 +768,54 @@ class InheritanceManagerTests(TestCase):
self.assertEqual(list(queryset), [{'id': self.child1.pk}])
+ @skipUnless(django.VERSION >= (1, 9, 0), "test only applies to Django 1.9+")
+ def test_dj19_values_list_on_select_subclasses(self):
+ """
+ Using `select_subclasses` in conjunction with `values_list()` raised an
+ exception in `_get_sub_obj_recurse()` because the result of `values_list()`
+ is either a `tuple` or primitive objects if `flat=True` is specified,
+ because no type checking was done prior to fetching child nodes.
+
+ Django versions below 1.9 are not affected by this bug.
+ """
+
+ # Querysets are cast to lists to force immediate evaluation.
+ # No exceptions must be thrown.
+
+ # No argument to select_subclasses
+ objs_1 = list(
+ self.get_manager().
+ select_subclasses().
+ values_list('id')
+ )
+
+ # String argument to select_subclasses
+ objs_2 = list(
+ self.get_manager().
+ select_subclasses(
+ "inheritancemanagertestchild2"
+ ).
+ values_list('id')
+ )
+
+ # String argument to select_subclasses
+ objs_3 = list(
+ self.get_manager().
+ select_subclasses(
+ InheritanceManagerTestChild2
+ ).
+ values_list('id')
+ )
+
+ assert all((
+ isinstance(objs_1, list),
+ isinstance(objs_2, list),
+ isinstance(objs_3, list),
+ ))
+
+ assert objs_1 == objs_2 == objs_3
+
+
class InheritanceManagerUsingModelsTests(TestCase):
def setUp(self):
@@ -1682,6 +1730,11 @@ class InheritedFieldTrackerTests(FieldTrackerTests):
self.assertRaises(FieldError, self.tracker.has_changed, 'name2')
+class FieldTrackerInheritedForeignKeyTests(FieldTrackerForeignKeyTests):
+
+ tracked_class = InheritedTrackedFK
+
+
class ModelTrackerTests(FieldTrackerTests):
tracked_class = ModelTracked
diff --git a/model_utils/tracker.py b/model_utils/tracker.py
index be5a7ff..a9c7f70 100644
--- a/model_utils/tracker.py
+++ b/model_utils/tracker.py
@@ -63,7 +63,7 @@ class FieldInstanceTracker(object):
def init_deferred_fields(self):
self.instance._deferred_fields = []
- if not self.instance._deferred:
+ if hasattr(self.instance, '_deferred') and not self.instance._deferred:
return
class DeferredAttributeTracker(DeferredAttribute):
@@ -101,7 +101,7 @@ class FieldTracker(object):
def get_field_map(self, cls):
"""Returns dict mapping fields names to model attribute names"""
field_map = dict((field, field) for field in self.fields)
- all_fields = dict((f.name, f.attname) for f in cls._meta.local_fields)
+ all_fields = dict((f.name, f.attname) for f in cls._meta.fields)
field_map.update(**dict((k, v) for (k, v) in all_fields.items()
if k in field_map))
return field_map
@@ -113,7 +113,7 @@ class FieldTracker(object):
def finalize_class(self, sender, **kwargs):
if self.fields is None:
- self.fields = (field.attname for field in sender._meta.local_fields)
+ self.fields = (field.attname for field in sender._meta.fields)
self.fields = set(self.fields)
self.field_map = self.get_field_map(sender)
models.signals.post_init.connect(self.initialize_tracker)
diff --git a/requirements.txt b/requirements.txt
new file mode 100644
index 0000000..082f7fb
--- /dev/null
+++ b/requirements.txt
@@ -0,0 +1,3 @@
+tox
+sphinx
+twine
diff --git a/setup.py b/setup.py
index feb5ffc..d894b58 100644
--- a/setup.py
+++ b/setup.py
@@ -1,21 +1,29 @@
-from os.path import join
+import os
from setuptools import setup, find_packages
-long_description = (open('README.rst').read() +
- open('CHANGES.rst').read() +
- open('TODO.rst').read())
+def long_desc(root_path):
+ FILES = ['README.rst', 'CHANGES.rst']
+ for filename in FILES:
+ filepath = os.path.realpath(os.path.join(root_path, filename))
+ if os.path.isfile(filepath):
+ with open(filepath, mode='r') as f:
+ yield f.read()
-def get_version():
- with open(join('model_utils', '__init__.py')) as f:
+HERE = os.path.abspath(os.path.dirname(__file__))
+long_description = "\n\n".join(long_desc(HERE))
+
+
+def get_version(root_path):
+ with open(os.path.join(root_path, 'model_utils', '__init__.py')) as f:
for line in f:
if line.startswith('__version__ ='):
return line.split('=')[1].strip().strip('"\'')
setup(
name='django-model-utils',
- version=get_version(),
+ version=get_version(HERE),
description='Django model mixins and utilities',
long_description=long_description,
author='Carl Meyer',
@@ -33,9 +41,9 @@ setup(
'Programming Language :: Python :: 2.6',
'Programming Language :: Python :: 2.7',
'Programming Language :: Python :: 3',
- 'Programming Language :: Python :: 3.2',
'Programming Language :: Python :: 3.3',
'Programming Language :: Python :: 3.4',
+ 'Programming Language :: Python :: 3.5',
'Framework :: Django',
],
zip_safe=False,
diff --git a/tox.ini b/tox.ini
index 40aa033..b096f7a 100644
--- a/tox.ini
+++ b/tox.ini
@@ -1,27 +1,28 @@
[tox]
envlist =
py26-django{14,15,16},
- py27-django14, py27-django15_nosouth,
- py{27,32,33}-django{15,16,17,18,_trunk},
- py27-django19,
- py34-django{17,18,19,_trunk},
+ py27-django{14,19,110,_trunk}, py27-django15_nosouth,
+ py{27,33}-django{15,16,17,18},
+ py34-django{17,18,19,110,_trunk},
+ py35-django{18,19,110,_trunk},
[testenv]
basepython =
py26: python2.6
py27: python2.7
- py32: python3.2
py33: python3.3
py34: python3.4
+ py35: python3.5
deps =
coverage == 3.6
- django14: Django==1.4.18
- django15{,_nosouth}: Django==1.5.12
- django16: Django==1.6.10
- django17: Django==1.7.7
- django18: Django==1.8.5
- django19: Django==1.9
+ django14: Django>=1.4,<1.5
+ django15{,_nosouth}: Django>=1.5,<1.6
+ django16: Django>=1.6,<1.7
+ django17: Django>=1.7,<1.8
+ django18: Django>=1.8,<1.9
+ django19: Django>=1.9,<1.10
+ django110: Django>=1.10,<1.11
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