[Python-modules-commits] [django-taggit] 01/03: New upstream version 0.22.1

Michal Cihar nijel at moszumanska.debian.org
Mon Jul 10 18:02:08 UTC 2017


This is an automated email from the git hooks/post-receive script.

nijel pushed a commit to branch master
in repository django-taggit.

commit 08483d4124981017904531aec24c4a6394ad8105
Author: Michal Čihař <nijel at debian.org>
Date:   Mon Jul 10 19:57:04 2017 +0200

    New upstream version 0.22.1
---
 AUTHORS                                |  1 +
 CHANGELOG.txt                          | 35 +++++++++++++
 PKG-INFO                               |  7 +--
 README.rst                             |  2 +-
 django_taggit.egg-info/PKG-INFO        |  7 +--
 django_taggit.egg-info/SOURCES.txt     |  2 +
 docs/contributing.txt                  | 95 ++++++++++++++++++++++++++++++++++
 docs/external_apps.txt                 | 33 +++++-------
 docs/index.txt                         |  3 +-
 runtests.py                            |  6 +++
 setup.cfg                              |  4 +-
 setup.py                               |  6 +--
 taggit/__init__.py                     |  2 +-
 taggit/locale/es/LC_MESSAGES/django.po |  4 +-
 taggit/managers.py                     | 92 +++++++++++---------------------
 taggit/models.py                       | 24 +++++----
 taggit/utils.py                        |  8 +--
 tests/forms.py                         |  2 +-
 tests/migrations/0002_uuid_models.py   | 54 +++++++++++++++++++
 tests/models.py                        | 26 +++++++++-
 tests/tests.py                         | 54 ++++++++++++++-----
 tox.ini                                | 17 +++++-
 22 files changed, 350 insertions(+), 134 deletions(-)

diff --git a/AUTHORS b/AUTHORS
index b66b86b..ccee40a 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -14,3 +14,4 @@ idle sign <idlesign at yandex.ru>
 Charles Leifer
 Florian Apolloner <apollo13 at apolloner.eu>
 Andrew Pryde <andrew at rocketpod.co.uk>
+John Whitlock <jwhitlock at mozilla.com>
diff --git a/CHANGELOG.txt b/CHANGELOG.txt
index 2b37b17..36de58c 100644
--- a/CHANGELOG.txt
+++ b/CHANGELOG.txt
@@ -1,6 +1,41 @@
 Changelog
 =========
 
+0.22.1 (2017-04-22)
+~~~~~~~~~~~~~~~~~~~
+ * Update spanish translation
+  * https://github.com/alex/django-taggit/pull/473
+ * Add testing for Django 1.11 and Python 3.6
+  * https://github.com/alex/django-taggit/pull/475
+ * introduce isort and flake8 in the CI
+  * https://github.com/alex/django-taggit/pull/476
+ * [docs] Fixed links to external apps
+  * https://github.com/alex/django-taggit/pull/481
+ * Improved auto-slug in TagBase to support UUID pk
+  * https://github.com/alex/django-taggit/pull/482
+ * [docs] Added contribution guidelines
+  * https://github.com/alex/django-taggit/pull/480
+
+0.22.0 (2017-01-29)
+~~~~~~~~~~~~~~~~~~~
+ * **Backwards incompatible:** Drop support for Django 1.7
+  * https://github.com/alex/django-taggit/pull/465
+
+0.21.6 (2017-01-25)
+~~~~~~~~~~~~~~~~~~~
+ * Fix case-insensitive tag creation when setting to a mix of new and existing tags are used
+  * https://github.com/alex/django-taggit/pull/464
+
+0.21.5 (2017-01-21)
+~~~~~~~~~~~~~~~~~~~
+ * Check for case-insensitive duplicates when creating new tags
+  * https://github.com/alex/django-taggit/pull/461
+
+0.21.4 (2017-01-10)
+~~~~~~~~~~~~~~~~~~~
+ * Support __gt__ and __lt__ ordering on Tags
+  * https://github.com/alex/django-taggit/pull/456
+
 0.21.3 (2016-10-07)
 ~~~~~~~~~~~~~~~~~~~
  * Fix list view
diff --git a/PKG-INFO b/PKG-INFO
index 57749c7..e3d0036 100644
--- a/PKG-INFO
+++ b/PKG-INFO
@@ -1,6 +1,6 @@
 Metadata-Version: 1.1
 Name: django-taggit
-Version: 0.21.3
+Version: 0.22.1
 Summary: django-taggit is a reusable Django application for simple tagging.
 Home-page: http://github.com/alex/django-taggit/tree/master
 Author: Alex Gaynor
@@ -44,7 +44,7 @@ Description: django-taggit
         
         Tags will show up for you automatically in forms and the admin.
         
-        ``django-taggit`` requires Django 1.7 or greater.
+        ``django-taggit`` requires Django 1.8 or greater.
         
         For more info check out the `documentation <https://django-taggit.readthedocs.io/en/latest/>`_.  And for questions about usage or
         development you can contact the
@@ -54,10 +54,10 @@ Platform: UNKNOWN
 Classifier: Development Status :: 5 - Production/Stable
 Classifier: Environment :: Web Environment
 Classifier: Framework :: Django
-Classifier: Framework :: Django :: 1.7
 Classifier: Framework :: Django :: 1.8
 Classifier: Framework :: Django :: 1.9
 Classifier: Framework :: Django :: 1.10
+Classifier: Framework :: Django :: 1.11
 Classifier: Intended Audience :: Developers
 Classifier: License :: OSI Approved :: BSD License
 Classifier: Operating System :: OS Independent
@@ -66,3 +66,4 @@ Classifier: Programming Language :: Python :: 2.7
 Classifier: Programming Language :: Python :: 3.3
 Classifier: Programming Language :: Python :: 3.4
 Classifier: Programming Language :: Python :: 3.5
+Classifier: Programming Language :: Python :: 3.6
diff --git a/README.rst b/README.rst
index 21be1d3..c5b53b8 100644
--- a/README.rst
+++ b/README.rst
@@ -36,7 +36,7 @@ Then you can use the API like so:
 
 Tags will show up for you automatically in forms and the admin.
 
-``django-taggit`` requires Django 1.7 or greater.
+``django-taggit`` requires Django 1.8 or greater.
 
 For more info check out the `documentation <https://django-taggit.readthedocs.io/en/latest/>`_.  And for questions about usage or
 development you can contact the
diff --git a/django_taggit.egg-info/PKG-INFO b/django_taggit.egg-info/PKG-INFO
index 57749c7..e3d0036 100644
--- a/django_taggit.egg-info/PKG-INFO
+++ b/django_taggit.egg-info/PKG-INFO
@@ -1,6 +1,6 @@
 Metadata-Version: 1.1
 Name: django-taggit
-Version: 0.21.3
+Version: 0.22.1
 Summary: django-taggit is a reusable Django application for simple tagging.
 Home-page: http://github.com/alex/django-taggit/tree/master
 Author: Alex Gaynor
@@ -44,7 +44,7 @@ Description: django-taggit
         
         Tags will show up for you automatically in forms and the admin.
         
-        ``django-taggit`` requires Django 1.7 or greater.
+        ``django-taggit`` requires Django 1.8 or greater.
         
         For more info check out the `documentation <https://django-taggit.readthedocs.io/en/latest/>`_.  And for questions about usage or
         development you can contact the
@@ -54,10 +54,10 @@ Platform: UNKNOWN
 Classifier: Development Status :: 5 - Production/Stable
 Classifier: Environment :: Web Environment
 Classifier: Framework :: Django
-Classifier: Framework :: Django :: 1.7
 Classifier: Framework :: Django :: 1.8
 Classifier: Framework :: Django :: 1.9
 Classifier: Framework :: Django :: 1.10
+Classifier: Framework :: Django :: 1.11
 Classifier: Intended Audience :: Developers
 Classifier: License :: OSI Approved :: BSD License
 Classifier: Operating System :: OS Independent
@@ -66,3 +66,4 @@ Classifier: Programming Language :: Python :: 2.7
 Classifier: Programming Language :: Python :: 3.3
 Classifier: Programming Language :: Python :: 3.4
 Classifier: Programming Language :: Python :: 3.5
+Classifier: Programming Language :: Python :: 3.6
diff --git a/django_taggit.egg-info/SOURCES.txt b/django_taggit.egg-info/SOURCES.txt
index 76ebc25..3ebdde7 100644
--- a/django_taggit.egg-info/SOURCES.txt
+++ b/django_taggit.egg-info/SOURCES.txt
@@ -17,6 +17,7 @@ docs/admin.txt
 docs/api.txt
 docs/changelog.txt
 docs/conf.py
+docs/contributing.txt
 docs/custom_tagging.txt
 docs/external_apps.txt
 docs/forms.txt
@@ -70,5 +71,6 @@ tests/settings.py
 tests/tests.py
 tests/urls.py
 tests/migrations/0001_initial.py
+tests/migrations/0002_uuid_models.py
 tests/migrations/__init__.py
 tests/templates/tests/food_tag_list.html
\ No newline at end of file
diff --git a/docs/contributing.txt b/docs/contributing.txt
new file mode 100644
index 0000000..4a67afc
--- /dev/null
+++ b/docs/contributing.txt
@@ -0,0 +1,95 @@
+Contributing to taggit
+======================
+
+Thank you for taking the time to contribute to django-taggit.
+
+Follow these guidelines to speed up the process.
+
+.. contents:: **Table of Contents**:
+   :backlinks: none
+   :depth: 3
+
+Reach out before you start
+--------------------------
+
+Before opening a new issue, try the following steps:
+
+- look if somebody else has already started working on the same issue
+  by looking in the `github issues <https://github.com/alex/django-taggit/issues>`_
+  and `pull requests <https://github.com/alex/django-taggit/pulls>`_
+- look also in the `django-taggit mailinglist <http://groups.google.com/group/django-taggit>`_
+- announce your intentions by opening a new issue
+- present yourself on the mailing list
+
+Fork repo and install your fork
+-------------------------------
+
+Once you have forked this repository to your own github account or organization,
+install your own fork in your development environment:
+
+.. code-block:: shell
+
+    git clone git at github.com:<your_fork>/django-taggit.git
+    cd django-taggit
+    python setup.py develop
+
+Running tests
+-------------
+
+.. code-block:: shell
+
+    make test
+
+Opening the django shell
+------------------------
+
+.. code-block:: shell
+
+    ./manage.py shell
+
+Creating new migrations
+---------------------
+
+.. code-block:: shell
+
+    ./manage.py makemigrations
+
+
+Follow style conventions (PEP8, isort)
+--------------------------------------
+
+Check that your changes are not breaking the style conventions with:
+
+.. code-block:: shell
+
+    flake8 taggit
+    python setup.py isort
+
+For more information, please see:
+
+- `PEP8: Style Guide for Python Code <https://www.python.org/dev/peps/pep-0008/>`_
+- `isort: a python utility / library to sort imports <https://github.com/timothycrosley/isort>`_
+
+Update documentation
+--------------------
+
+If you introduce new features or change existing documented behavior,
+please remember to update the documentation!
+
+The documentation is located in the ``/docs`` directory
+of the repository.
+
+To do work on the docs, proceed with the following steps:
+
+.. code-block:: shell
+
+    cd docs/
+    pip install sphinx
+    # update the text files with your favorite text editor
+    make html
+
+Send pull request
+-----------------
+
+Now is time to push your changes to github and open a
+`pull request <https://github.com/alex/django-taggit/pulls>`_!
diff --git a/docs/external_apps.txt b/docs/external_apps.txt
index 959d8c9..0d1a906 100644
--- a/docs/external_apps.txt
+++ b/docs/external_apps.txt
@@ -10,29 +10,24 @@ of interest.
     Despite their mention here, the following applications are in no way
     official, nor have they in any way been reviewed or tested.
 
-
 If you have an application that you'd like to see listed here, simply fork
-``taggit`` on `github`__, add it to this list, and send a pull request.
-
+`django-taggit on github <https://github.com/alex/django-taggit>`_,
+add it to this list, and send a pull request.
 
- * ``django-taggit-helpers``: Makes it easier to work with admin pages of models
+ * `django-taggit-helpers <https://github.com/mfcovington/django-taggit-helpers>`_:
+   Makes it easier to work with admin pages of models
    associated with ``taggit`` tags by adding helper classes: ``TaggitCounter``,
    ``TaggitListFilter``, ``TaggitStackedInline``, ``TaggitTabularInline``.
-   Available on `github`__.
- * ``django-taggit-labels``: Provides a clickable label widget for the
+ * `django-taggit-labels <https://github.com/bennylope/django-taggit-labels>`_:
+   Provides a clickable label widget for the
    Django admin for user friendly selection from managed tag sets.
- * ``django-taggit-serializer``: Adds functionality for using ``taggit`` with
-   ``django-rest-framework``. Available on `github`__.
- * ``django-taggit-suggest``: Provides support for defining keyword and regular
+ * `django-taggit-serializer <https://github.com/glemmaPaul/django-taggit-serializer>`_:
+   Adds functionality for using ``taggit`` with
+   ``django-rest-framework``.
+ * `django-taggit-suggest <https://github.com/frankwiles/django-taggit-suggest>`_:
+   Provides support for defining keyword and regular
    expression rules for suggesting new tags for content.  This used to be
-   available at ``taggit.contrib.suggest``.  Available on `github`__.
- * ``django-taggit-templatetags``: Provides several templatetags, including one
+   available at ``taggit.contrib.suggest``.
+ * `django-taggit-templatetags <https://github.com/feuervogel/django-taggit-templatetags>`_:
+   Provides several templatetags, including one
    for tag clouds, to expose various ``taggit`` APIs directly to templates.
-   Available on `github`__.
-
-__ https://github.com/alex/django-taggit
-__ https://github.com/mfcovington/django-taggit-helpers
-__ https://github.com/bennylope/django-taggit-labels
-__ https://github.com/glemmaPaul/django-taggit-serializer
-__ https://github.com/frankwiles/django-taggit-suggest
-__ https://github.com/feuervogel/django-taggit-templatetags
diff --git a/docs/index.txt b/docs/index.txt
index 7ce6bba..03d3a8e 100644
--- a/docs/index.txt
+++ b/docs/index.txt
@@ -4,7 +4,7 @@ Welcome to django-taggit's documentation!
 ``django-taggit`` is a reusable Django application designed to making adding
 tagging to your project easy and fun.
 
-``django-taggit`` works with Django 1.7+ and Python 2.7-3.X.
+``django-taggit`` works with Django 1.8+ and Python 2.7-3.X.
 
 .. toctree::
    :maxdepth: 2
@@ -14,6 +14,7 @@ tagging to your project easy and fun.
    admin
    api
    custom_tagging
+   contributing
    external_apps
    changelog
 
diff --git a/runtests.py b/runtests.py
index 36a7d4e..8dde330 100755
--- a/runtests.py
+++ b/runtests.py
@@ -18,6 +18,12 @@ if not settings.configured:
             'tests',
         ],
         MIDDLEWARE_CLASSES=[],
+        TEMPLATES=[
+            {
+                'BACKEND': 'django.template.backends.django.DjangoTemplates',
+                'APP_DIRS': True,
+            }
+        ],
     )
 
 
diff --git a/setup.cfg b/setup.cfg
index 352f752..1b22ebb 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -5,8 +5,9 @@ license-file = LICENSE
 universal = 1
 
 [flake8]
+max-line-length = 119
 ignore = E501,E302
-exclude = migrations
+exclude = migrations,docs
 
 [isort]
 forced_separate = tests,taggit
@@ -15,5 +16,4 @@ skip = migrations,.tox,docs
 [egg_info]
 tag_build = 
 tag_date = 0
-tag_svn_revision = 0
 
diff --git a/setup.py b/setup.py
index c250552..40f04dd 100644
--- a/setup.py
+++ b/setup.py
@@ -2,7 +2,6 @@ from setuptools import find_packages, setup
 
 import taggit
 
-
 with open('README.rst') as f:
     readme = f.read()
 
@@ -15,7 +14,7 @@ setup(
     author_email='alex.gaynor at gmail.com',
     url='http://github.com/alex/django-taggit/tree/master',
     packages=find_packages(exclude=('tests*',)),
-    package_data = {
+    package_data={
         'taggit': [
             'locale/*/LC_MESSAGES/*',
         ],
@@ -25,10 +24,10 @@ setup(
         'Development Status :: 5 - Production/Stable',
         'Environment :: Web Environment',
         'Framework :: Django',
-        'Framework :: Django :: 1.7',
         'Framework :: Django :: 1.8',
         'Framework :: Django :: 1.9',
         'Framework :: Django :: 1.10',
+        'Framework :: Django :: 1.11',
         'Intended Audience :: Developers',
         'License :: OSI Approved :: BSD License',
         'Operating System :: OS Independent',
@@ -37,6 +36,7 @@ setup(
         'Programming Language :: Python :: 3.3',
         'Programming Language :: Python :: 3.4',
         'Programming Language :: Python :: 3.5',
+        'Programming Language :: Python :: 3.6',
     ],
     include_package_data=True,
     zip_safe=False,
diff --git a/taggit/__init__.py b/taggit/__init__.py
index 9b368b2..73c4dd9 100644
--- a/taggit/__init__.py
+++ b/taggit/__init__.py
@@ -1,3 +1,3 @@
-VERSION = (0, 21, 3)
+VERSION = (0, 22, 1)
 
 default_app_config = 'taggit.apps.TaggitAppConfig'
diff --git a/taggit/locale/es/LC_MESSAGES/django.po b/taggit/locale/es/LC_MESSAGES/django.po
index c4eb44e..957927c 100644
--- a/taggit/locale/es/LC_MESSAGES/django.po
+++ b/taggit/locale/es/LC_MESSAGES/django.po
@@ -20,7 +20,7 @@ msgstr ""
 
 #: forms.py:27
 msgid "Please provide a comma-separated list of tags."
-msgstr "Por favor provea una lista de etiquetas separadas por coma."
+msgstr "Por favor introduzca una lista de etiquetas separadas por coma."
 
 #: managers.py:297 models.py:101
 msgid "Tags"
@@ -36,7 +36,7 @@ msgstr "Nombre"
 
 #: models.py:47
 msgid "Slug"
-msgstr "Marquilla"
+msgstr "Slug"
 
 #: models.py:100
 msgid "Tag"
diff --git a/taggit/managers.py b/taggit/managers.py
index dc6ed72..7e6ad5c 100644
--- a/taggit/managers.py
+++ b/taggit/managers.py
@@ -12,36 +12,21 @@ from django.db.models import signals
 from django.db.models.fields import Field
 from django.db.models.fields.related import (ManyToManyRel, OneToOneRel,
                                              RelatedField)
+from django.db.models.query_utils import PathInfo
 from django.utils import six
 from django.utils.text import capfirst
 from django.utils.translation import ugettext_lazy as _
 
 from taggit.forms import TagField
 from taggit.models import CommonGenericTaggedItemBase, TaggedItem
-from taggit.utils import (_get_field, _related_model, _remote_field,
+from taggit.utils import (_related_model, _remote_field,
                           require_instance_manager)
 
-if VERSION < (1, 8):
-    # related.py was removed in Django 1.8
-
-    # Depending on how Django was updated, related.py could still exist
-    # on the users system even on Django 1.8+, so we check the Django
-    # version before importing it to make sure this doesn't get imported
-    # accidentally.
-    from django.db.models.related import RelatedObject
-else:
-    RelatedObject = None
-
-
 if VERSION >= (1, 9):
     from django.db.models.fields.related import lazy_related_operation
 else:
     from django.db.models.fields.related import add_lazy_relation
 
-try:
-    from django.db.models.query_utils import PathInfo
-except ImportError:  # Django < 1.8
-    from django.db.models.related import PathInfo
 
 class TaggableRel(ManyToManyRel):
     def __init__(self, field, related_name, through, to=None):
@@ -76,11 +61,8 @@ class ExtraJoinRestriction(object):
         self.col = col
         self.content_types = content_types
 
-    def as_sql(self, qn, connection):
-        # qn changed from a quoting function to be a compiler object in 1.8,
-        # which has a quote function
-        if VERSION >= (1, 8):
-            qn = qn.quote_name_unless_alias
+    def as_sql(self, compiler, connection):
+        qn = compiler.quote_name_unless_alias
         if len(self.content_types) == 1:
             extra_where = "%s.%s = %%s" % (qn(self.alias), qn(self.col))
         else:
@@ -197,7 +179,10 @@ class _TaggableManager(models.Manager):
                     "Cannot add {0} ({1}). Expected {2} or str.".format(
                         t, type(t), type(self.through.tag_model())))
 
-        if getattr(settings, 'TAGGIT_CASE_INSENSITIVE', False):
+        case_insensitive = getattr(settings, 'TAGGIT_CASE_INSENSITIVE', False)
+        manager = self.through.tag_model()._default_manager.using(db)
+
+        if case_insensitive:
             # Some databases can do case-insensitive comparison with IN, which
             # would be faster, but we can't rely on it or easily detect it.
             existing = []
@@ -205,28 +190,28 @@ class _TaggableManager(models.Manager):
 
             for name in str_tags:
                 try:
-                    tag = (self.through.tag_model()._default_manager
-                           .using(db)
-                           .get(name__iexact=name))
+                    tag = manager.get(name__iexact=name)
                     existing.append(tag)
                 except self.through.tag_model().DoesNotExist:
                     tags_to_create.append(name)
         else:
             # If str_tags has 0 elements Django actually optimizes that to not
             # do a query.  Malcolm is very smart.
-            existing = (self.through.tag_model()._default_manager
-                        .using(db)
-                        .filter(name__in=str_tags))
-
+            existing = manager.filter(name__in=str_tags)
             tags_to_create = str_tags - set(t.name for t in existing)
 
         tag_objs.update(existing)
 
         for new_tag in tags_to_create:
-            tag_objs.add(
-                self.through.tag_model()._default_manager
-                .using(db)
-                .create(name=new_tag))
+            if case_insensitive:
+                try:
+                    tag = manager.get(name__iexact=new_tag)
+                except self.through.tag_model().DoesNotExist:
+                    tag = manager.create(name=new_tag)
+            else:
+                tag = manager.create(name=new_tag)
+
+            tag_objs.add(tag)
 
         return tag_objs
 
@@ -340,7 +325,7 @@ class _TaggableManager(models.Manager):
         if len(lookup_keys) == 1:
             # Can we do this without a second query by using a select_related()
             # somehow?
-            f = _get_field(self.through, lookup_keys[0])
+            f = self.through._meta.get_field(lookup_keys[0])
             remote_field = _remote_field(f)
             rel_model = _related_model(_remote_field(f))
             objs = rel_model._default_manager.filter(**{
@@ -496,9 +481,6 @@ class TaggableManager(RelatedField, Field):
         return False
 
     def post_through_setup(self, cls):
-        if RelatedObject is not None:  # Django < 1.8
-            self.related = RelatedObject(cls, self.model, self)
-
         self.use_gfk = (
             self.through is None or issubclass(self.through, CommonGenericTaggedItemBase)
         )
@@ -511,9 +493,6 @@ class TaggableManager(RelatedField, Field):
             if not self.rel.to:
                 self.rel.to = self.through._meta.get_field("tag").rel.to
 
-        if RelatedObject is not None:  # Django < 1.8
-            self.related = RelatedObject(self.through, cls, self)
-
         if self.use_gfk:
             tagged_items = GenericRelation(self.through)
             tagged_items.contribute_to_class(cls, 'tagged_items')
@@ -546,10 +525,10 @@ class TaggableManager(RelatedField, Field):
         return self.model._meta.model_name
 
     def m2m_reverse_name(self):
-        return _get_field(self.through, 'tag').column
+        return self.through._meta.get_field('tag').column
 
     def m2m_reverse_field_name(self):
-        return _get_field(self.through, 'tag').name
+        return self.through._meta.get_field('tag').name
 
     def m2m_target_field_name(self):
         return self.model._meta.pk.name
@@ -591,7 +570,7 @@ class TaggableManager(RelatedField, Field):
             alias_to_join = rhs_alias
         else:
             alias_to_join = lhs_alias
-        extra_col = _get_field(self.through, 'content_type').column
+        extra_col = self.through._meta.get_field('content_type').column
         content_type_ids = [ContentType.objects.get_for_model(subclass).pk for
                             subclass in _get_subclasses(self.model)]
         if len(content_type_ids) == 1:
@@ -609,8 +588,8 @@ class TaggableManager(RelatedField, Field):
 
     def _get_mm_case_path_info(self, direct=False):
         pathinfos = []
-        linkfield1 = _get_field(self.through, 'content_object')
-        linkfield2 = _get_field(self.through, self.m2m_reverse_field_name())
+        linkfield1 = self.through._meta.get_field('content_object')
+        linkfield2 = self.through._meta.get_field(self.m2m_reverse_field_name())
         if direct:
             join1infos = linkfield1.get_reverse_path_info()
             join2infos = linkfield2.get_path_info()
@@ -625,7 +604,7 @@ class TaggableManager(RelatedField, Field):
         pathinfos = []
         from_field = self.model._meta.pk
         opts = self.through._meta
-        linkfield = _get_field(self.through, self.m2m_reverse_field_name())
+        linkfield = self.through._meta.get_field(self.m2m_reverse_field_name())
         if direct:
             join1infos = [PathInfo(self.model._meta, opts, [from_field], _remote_field(self), True, False)]
             join2infos = linkfield.get_path_info()
@@ -655,7 +634,7 @@ class TaggableManager(RelatedField, Field):
             return (("object_id", self.model._meta.pk.column),)
 
     def get_extra_restriction(self, where_class, alias, related_alias):
-        extra_col = _get_field(self.through, 'content_type').column
+        extra_col = self.through._meta.get_field('content_type').column
         content_type_ids = [ContentType.objects.get_for_model(subclass).pk
                             for subclass in _get_subclasses(self.model)]
         return ExtraJoinRestriction(related_alias, extra_col, content_type_ids)
@@ -665,7 +644,7 @@ class TaggableManager(RelatedField, Field):
 
     @property
     def related_fields(self):
-        return [(_get_field(self.through, 'object_id'), self.model._meta.pk)]
+        return [(self.through._meta.get_field('object_id'), self.model._meta.pk)]
 
     @property
     def foreign_related_fields(self):
@@ -674,20 +653,9 @@ class TaggableManager(RelatedField, Field):
 
 def _get_subclasses(model):
     subclasses = [model]
-    if VERSION < (1, 8):
-        all_fields = (_get_field(model, f) for f in model._meta.get_all_field_names())
-    else:
-        all_fields = model._meta.get_fields()
-    for field in all_fields:
-        # Django 1.8 +
-        if (not RelatedObject and isinstance(field, OneToOneRel) and
-                getattr(_remote_field(field.field), "parent_link", None)):
+    for field in model._meta.get_fields():
+        if isinstance(field, OneToOneRel) and getattr(_remote_field(field.field), "parent_link", None):
             subclasses.extend(_get_subclasses(field.related_model))
-
-        # < Django 1.8
-        if (RelatedObject and isinstance(field, RelatedObject) and
-                getattr(field.field.rel, "parent_link", None)):
-            subclasses.extend(_get_subclasses(field.model))
     return subclasses
 
 
diff --git a/taggit/models.py b/taggit/models.py
index 77ffc87..3ef9af1 100644
--- a/taggit/models.py
+++ b/taggit/models.py
@@ -10,8 +10,6 @@ from django.utils.encoding import python_2_unicode_compatible
 from django.utils.translation import ugettext_lazy as _
 from django.utils.translation import ugettext
 
-from taggit.utils import _get_field
-
 try:
     from unidecode import unidecode
 except ImportError:
@@ -27,11 +25,17 @@ class TagBase(models.Model):
     def __str__(self):
         return self.name
 
+    def __gt__(self, other):
+        return self.name.lower() > other.name.lower()
+
+    def __lt__(self, other):
+        return self.name.lower() < other.name.lower()
+
     class Meta:
         abstract = True
 
     def save(self, *args, **kwargs):
-        if not self.pk and not self.slug:
+        if self._state.adding and not self.slug:
             self.slug = self.slugify(self.name)
             from django.db import router
             using = kwargs.get("using") or router.db_for_write(
@@ -93,12 +97,12 @@ class ItemBase(models.Model):
 
     @classmethod
     def tag_model(cls):
-        field = _get_field(cls, 'tag')
+        field = cls._meta.get_field('tag')
         return field.remote_field.model if VERSION >= (1, 9) else field.rel.to
 
     @classmethod
     def tag_relname(cls):
-        field = _get_field(cls, 'tag')
+        field = cls._meta.get_field('tag')
         return field.remote_field.related_name if VERSION >= (1, 9) else field.rel.related_name
 
     @classmethod
@@ -188,13 +192,11 @@ class GenericTaggedItemBase(CommonGenericTaggedItemBase):
         abstract = True
 
 
-if VERSION >= (1, 8):
+class GenericUUIDTaggedItemBase(CommonGenericTaggedItemBase):
+    object_id = models.UUIDField(verbose_name=_('Object id'), db_index=True)
 
-    class GenericUUIDTaggedItemBase(CommonGenericTaggedItemBase):
-        object_id = models.UUIDField(verbose_name=_('Object id'), db_index=True)
-
-        class Meta:
-            abstract = True
+    class Meta:
+        abstract = True
 
 
 class TaggedItem(GenericTaggedItemBase, TaggedItemBase):
diff --git a/taggit/utils.py b/taggit/utils.py
index ab9fb37..4a866a4 100644
--- a/taggit/utils.py
+++ b/taggit/utils.py
@@ -9,13 +9,6 @@ from django.utils.encoding import force_text
 from django.utils.functional import wraps
 
 
-def _get_field(model, name):
-    if VERSION < (1, 8):
-        return model._meta.get_field_by_name(name)[0]
-    else:
-        return model._meta.get_field(name)
-
-
 def _remote_field(field):
     if VERSION < (1, 9):
         return field.rel
@@ -164,6 +157,7 @@ def get_func(key, default):
         get_func.cache[func_path] = func
         return func
 
+
 # Create a cache as an attribute on the function that way it can cache the
 # imported callable rather than re-importing it each time `parse_tags` or
 # `edit_string_for_tags` needs the callable.
diff --git a/tests/forms.py b/tests/forms.py
index 1acbbd4..080f647 100644
--- a/tests/forms.py
+++ b/tests/forms.py
@@ -1,6 +1,6 @@
 from __future__ import absolute_import, unicode_literals
 
-from django import VERSION, forms
+from django import forms
 
 from .models import (CustomPKFood, DirectCustomPKFood, DirectFood, Food,
                      OfficialFood)
diff --git a/tests/migrations/0002_uuid_models.py b/tests/migrations/0002_uuid_models.py
new file mode 100644
index 0000000..0eee358
--- /dev/null
+++ b/tests/migrations/0002_uuid_models.py
@@ -0,0 +1,54 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.10.7 on 2017-04-19 11:21
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+import django.db.models.deletion
+import taggit.managers
+import uuid
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('contenttypes', '0002_remove_content_type_name'),
+        ('tests', '0001_initial'),
+    ]
+
+    operations = [
+        migrations.CreateModel(
+            name='UUIDFood',
+            fields=[
+                ('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
+                ('name', models.CharField(max_length=50)),
+            ],
+        ),
+        migrations.CreateModel(
+            name='UUIDTag',
+            fields=[
+                ('name', models.CharField(max_length=100, unique=True, verbose_name='Name')),
+                ('slug', models.SlugField(max_length=100, unique=True, verbose_name='Slug')),
+                ('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
+            ],
+            options={
+                'abstract': False,
+            },
+        ),
+        migrations.CreateModel(
+            name='UUIDTaggedItem',
+            fields=[
+                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+                ('object_id', models.UUIDField(db_index=True, verbose_name='Object id')),
+                ('content_type', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='tests_uuidtaggeditem_tagged_items', to='contenttypes.ContentType', verbose_name='Content type')),
+                ('tag', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='tests_uuidtaggeditem_items', to='tests.UUIDTag')),
+            ],
+            options={
+                'abstract': False,
+            },
+        ),
+        migrations.AddField(
+            model_name='uuidfood',
+            name='tags',
+            field=taggit.managers.TaggableManager(help_text='A comma-separated list of tags.', through='tests.UUIDTaggedItem', to='tests.UUIDTag', verbose_name='Tags'),
+        ),
+    ]
diff --git a/tests/models.py b/tests/models.py
index a8ddf8a..393af2a 100644
--- a/tests/models.py
+++ b/tests/models.py
@@ -1,11 +1,14 @@
 from __future__ import unicode_literals
 
+import uuid
+
 from django.db import models
 from django.utils.encoding import python_2_unicode_compatible
 
 from taggit.managers import TaggableManager
 from taggit.models import (CommonGenericTaggedItemBase, GenericTaggedItemBase,
-                           Tag, TagBase, TaggedItem, TaggedItemBase)
+                           GenericUUIDTaggedItemBase, Tag, TagBase, TaggedItem,
+                           TaggedItemBase)
 
 
 # Ensure that two TaggableManagers with custom through model are allowed.
@@ -103,7 +106,6 @@ class TaggedCustomPKPet(TaggedItemBase):
 @python_2_unicode_compatible
 class DirectCustomPKFood(models.Model):
     name = models.CharField(max_length=50, primary_key=True)
-
     tags = TaggableManager(through=TaggedCustomPKFood)
 
     def __str__(self):
@@ -243,3 +245,23 @@ class Parent(models.Model):
 
 class Child(Parent):
     pass
+
+
+ at python_2_unicode_compatible
+class UUIDFood(models.Model):
+    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
+    name = models.CharField(max_length=50)
+    tags = TaggableManager(through='UUIDTaggedItem')
+
+    def __str__(self):
+        return self.name
+
+
+class UUIDTag(TagBase):
+    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
+
+
+class UUIDTaggedItem(GenericUUIDTaggedItemBase):
+    tag = models.ForeignKey(UUIDTag,
+                            related_name='%(app_label)s_%(class)s_items',
+                            on_delete=models.CASCADE)
diff --git a/tests/tests.py b/tests/tests.py
index 01109ab..385c47a 100644
--- a/tests/tests.py
+++ b/tests/tests.py
@@ -3,18 +3,18 @@ from __future__ import absolute_import, unicode_literals
 import sys
 import warnings
 from unittest import TestCase as UnitTestCase
-from unittest import skipIf, skipUnless
 
 import django
 import mock
 from django.contrib.contenttypes.models import ContentType
 from django.core import serializers
-from django.core.exceptions import ImproperlyConfigured, ValidationError
+from django.core.exceptions import ValidationError
 from django.core.management import call_command
 from django.db import connection, models
 from django.test import RequestFactory, TestCase, TransactionTestCase
 from django.test.utils import override_settings
 from django.utils.encoding import force_text
+from django.views.generic.list import ListView
 
 from .forms import (CustomPKFoodForm, DirectCustomPKFoodForm, DirectFoodForm,
                     FoodForm, OfficialFoodForm)
@@ -24,13 +24,14 @@ from .models import (Article, Child, CustomManager, CustomPKFood,
                      DirectHousePet, DirectPet, Food, HousePet, Movie,
                      OfficialFood, OfficialHousePet, OfficialPet, OfficialTag,
                      OfficialThroughModel, Pet, Photo, TaggedCustomPK,
-                     TaggedCustomPKFood, TaggedFood)
+                     TaggedCustomPKFood, TaggedFood,
+                     UUIDFood, UUIDTag)
 
 from taggit.managers import TaggableManager, _TaggableManager
 from taggit.models import Tag, TaggedItem
-from taggit.views import tagged_object_list, TagListMixin
 from taggit.utils import (_related_model, _remote_field, edit_string_for_tags,
                           parse_tags)
+from taggit.views import TagListMixin, tagged_object_list
 
 
 class BaseTaggingTest(object):
@@ -110,6 +111,18 @@ class TagModelTestCase(BaseTaggingTransactionTestCase):
                 r"Expected <class 'django.db.models.base.ModelBase'> or str.")):
             apple.tags.add(1)
 
+    def test_gt(self):
+        high = self.tag_model.objects.create(name='high')
+        low = self.tag_model.objects.create(name='Low')
+        self.assertTrue(low > high)
+        self.assertFalse(high > low)
+
+    def test_lt(self):
+        high = self.tag_model.objects.create(name='high')
+        low = self.tag_model.objects.create(name='Low')
+        self.assertTrue(high < low)
+        self.assertFalse(low < high)
+
 
 class TagModelDirectTestCase(TagModelTestCase):
     food_model = DirectFood
@@ -598,13 +611,8 @@ class TaggableManagerTestCase(BaseTaggingTestCase):
             self.assertTrue(hasattr(field, 'rel'))
             self.assertTrue(hasattr(field.rel, 'to'))
 
-        # This API has changed in Django 1.8
-        # https://code.djangoproject.com/ticket/21414
-        if django.VERSION >= (1, 8):
-            self.assertEqual(self.food_model, field.model)
-            self.assertEqual(self.tag_model, _remote_field(field).model)
-        else:
-            self.assertEqual(self.food_model, field.related.model)
+        self.assertEqual(self.food_model, field.model)
+        self.assertEqual(self.tag_model, _remote_field(field).model)
 
     def test_names_method(self):
         apple = self.food_model.objects.create(name="apple")
@@ -656,6 +664,23 @@ class TaggableManagerTestCase(BaseTaggingTestCase):
         orange.tags.add('spain')
         self.assertEqual(list(orange.tags.all()), [spain])
 
+    @override_settings(TAGGIT_CASE_INSENSITIVE=True)
+    def test_with_case_insensitive_option_and_creation(self):
+        orange = self.food_model.objects.create(name="orange")
+        orange.tags.add('spain', 'Spain')
+        tag_names = list(orange.tags.names())
+        self.assertEqual(len(tag_names), 1, tag_names)
+
+    @override_settings(TAGGIT_CASE_INSENSITIVE=True)
+    def test_with_case_insensitive_option_new_and_old(self):
... 65 lines suppressed ...

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/python-modules/packages/django-taggit.git



More information about the Python-modules-commits mailing list