[Python-modules-commits] [django-taggit] 03/04: Imported Upstream version 0.18.2

Michal Cihar nijel at moszumanska.debian.org
Thu May 12 07:31:54 UTC 2016


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

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

commit 47ef83552512e3cdbf739ba03a77defa2a757a4b
Author: Michal Čihař <nijel at debian.org>
Date:   Thu May 12 09:30:08 2016 +0200

    Imported Upstream version 0.18.2
---
 CHANGELOG.txt                    | 10 +++++
 PKG-INFO                         |  2 +-
 django_taggit.egg-info/PKG-INFO  |  2 +-
 docs/api.txt                     |  2 +
 docs/custom_tagging.txt          |  2 +-
 runtests.py                      |  5 +++
 taggit/__init__.py               |  2 +-
 taggit/managers.py               | 93 ++++++++++++++++++++++++----------------
 taggit/utils.py                  | 14 ++++++
 tests/migrations/0001_initial.py | 46 ++++++++++----------
 tests/models.py                  | 16 +++----
 tests/tests.py                   | 61 +++++++++++++++++++-------
 tox.ini                          | 12 ++++++
 13 files changed, 181 insertions(+), 86 deletions(-)

diff --git a/CHANGELOG.txt b/CHANGELOG.txt
index 01cb0bc..507dabb 100644
--- a/CHANGELOG.txt
+++ b/CHANGELOG.txt
@@ -1,6 +1,16 @@
 Changelog
 =========
 
+0.18.2 (2016-05-08)
+~~~~~~~~~~~~~~~~~~~
+ * Add the min_count parameter to managers.most_common function
+  * https://github.com/alex/django-taggit/pull/400
+
+0.18.1 (2016-03-30)
+~~~~~~~~~~~~~~~~~~~
+ * Address deprecation warnings
+  * https://github.com/alex/django-taggit/pull/385
+
 0.18.0 (2016-01-18)
 ~~~~~~~~~~~~~~~~~~~
  * Add option to override default tag string parsing
diff --git a/PKG-INFO b/PKG-INFO
index f48cccb..0159924 100644
--- a/PKG-INFO
+++ b/PKG-INFO
@@ -1,6 +1,6 @@
 Metadata-Version: 1.1
 Name: django-taggit
-Version: 0.18.0
+Version: 0.18.2
 Summary: django-taggit is a reusable Django application for simple tagging.
 Home-page: http://github.com/alex/django-taggit/tree/master
 Author: Alex Gaynor
diff --git a/django_taggit.egg-info/PKG-INFO b/django_taggit.egg-info/PKG-INFO
index f48cccb..0159924 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.18.0
+Version: 0.18.2
 Summary: django-taggit is a reusable Django application for simple tagging.
 Home-page: http://github.com/alex/django-taggit/tree/master
 Author: Alex Gaynor
diff --git a/docs/api.txt b/docs/api.txt
index ff6b7c1..26dd453 100644
--- a/docs/api.txt
+++ b/docs/api.txt
@@ -42,6 +42,8 @@ playing around with the API.
         ``QuerySet``is ordered by ``num_times``, descending.  The ``QuerySet``
         is lazily evaluated, and can be sliced efficiently.
 
+        :param min_count: Specify a min count to limit the returned queryset
+
     .. method:: similar_objects()
 
         Returns a list (not a lazy ``QuerySet``) of other objects tagged
diff --git a/docs/custom_tagging.txt b/docs/custom_tagging.txt
index 29d4b75..0c490db 100644
--- a/docs/custom_tagging.txt
+++ b/docs/custom_tagging.txt
@@ -191,7 +191,7 @@ a list of tags to a string representation and use the setting
 ``TAGGIT_STRING_FROM_TAGS`` to override the default value (which is
 :func:`taggit.utils._edit_string_for_tags`)::
 
-    def comma_joiner(tag_string):
+    def comma_joiner(tags):
         return ', '.join(t.name for t in tags)
 
 If the functions above were defined in a module, ``appname.utils``, then your
diff --git a/runtests.py b/runtests.py
index 57e9aa0..dedd55a 100755
--- a/runtests.py
+++ b/runtests.py
@@ -1,5 +1,6 @@
 #!/usr/bin/env python
 import sys
+import warnings
 
 from django.conf import settings
 from django.core.management import execute_from_command_line
@@ -21,6 +22,10 @@ if not settings.configured:
     )
 
 
+warnings.simplefilter('default', DeprecationWarning)
+warnings.simplefilter('default', PendingDeprecationWarning)
+
+
 def runtests():
     argv = sys.argv[:1] + ['test'] + sys.argv[1:]
     execute_from_command_line(argv)
diff --git a/taggit/__init__.py b/taggit/__init__.py
index 15f904d..870fd1b 100644
--- a/taggit/__init__.py
+++ b/taggit/__init__.py
@@ -1 +1 @@
-VERSION = (0, 18, 0)
+VERSION = (0, 18, 2)
diff --git a/taggit/managers.py b/taggit/managers.py
index 3d78d8f..6dec89a 100644
--- a/taggit/managers.py
+++ b/taggit/managers.py
@@ -3,19 +3,18 @@ from __future__ import unicode_literals
 from operator import attrgetter
 
 from django import VERSION
-from django.contrib.contenttypes.models import ContentType
 from django.conf import settings
+from django.contrib.contenttypes.models import ContentType
 from django.db import models, router
 from django.db.models.fields import Field
-from django.db.models.fields.related import (add_lazy_relation, ManyToManyRel,
-                                             OneToOneRel, RelatedField)
+from django.db.models.fields.related import ManyToManyRel, OneToOneRel, RelatedField
 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, require_instance_manager
+from taggit.utils import _get_field, _related_model, _remote_field, require_instance_manager
 
 if VERSION < (1, 8):
     # related.py was removed in Django 1.8
@@ -28,6 +27,13 @@ if VERSION < (1, 8):
 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.contrib.contenttypes.fields import GenericRelation
 except ImportError:  # django < 1.7
@@ -43,7 +49,7 @@ except ImportError:  # Django < 1.8
 
 
 def _model_name(model):
-    if VERSION < (1, 7):
+    if VERSION < (1, 6):
         return model._meta.module_name
     else:
         return model._meta.model_name
@@ -83,6 +89,10 @@ class ExtraJoinRestriction(object):
         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
         if len(self.content_types) == 1:
             extra_where = "%s.%s = %%s" % (qn(self.alias), qn(self.col))
         else:
@@ -216,10 +226,14 @@ class _TaggableManager(models.Manager):
     def clear(self):
         self.through.objects.filter(**self._lookup_kwargs()).delete()
 
-    def most_common(self):
-        return self.get_queryset().annotate(
+    def most_common(self, min_count=None):
+        queryset = self.get_queryset().annotate(
             num_times=models.Count(self.through.tag_relname())
         ).order_by('-num_times')
+        if min_count:
+            queryset = queryset.filter(num_times__gte=min_count)
+
+        return queryset
 
     @require_instance_manager
     def similar_objects(self):
@@ -237,12 +251,13 @@ class _TaggableManager(models.Manager):
             # Can we do this without a second query by using a select_related()
             # somehow?
             f = _get_field(self.through, lookup_keys[0])
-            rel_model = f.rel.model if VERSION >= (1, 9) else f.rel.to
+            remote_field = _remote_field(f)
+            rel_model = _related_model(_remote_field(f))
             objs = rel_model._default_manager.filter(**{
-                "%s__in" % f.rel.field_name: [r["content_object"] for r in qs]
+                "%s__in" % remote_field.field_name: [r["content_object"] for r in qs]
             })
             for obj in objs:
-                items[(getattr(obj, f.rel.field_name),)] = obj
+                items[(getattr(obj, remote_field.field_name),)] = obj
         else:
             preload = {}
             for result in qs:
@@ -323,22 +338,17 @@ class TaggableManager(RelatedField, Field):
             del kwargs[kwarg]
         # Add arguments related to relations.
         # Ref: https://github.com/alex/django-taggit/issues/206#issuecomment-37578676
-        if isinstance(self.rel.through, six.string_types):
-            kwargs['through'] = self.rel.through
-        elif not self.rel.through._meta.auto_created:
-            kwargs['through'] = "%s.%s" % (self.rel.through._meta.app_label, self.rel.through._meta.object_name)
-
-        # rel.to renamed to remote_field.model in Django 1.9
-        if VERSION >= (1, 9):
-            if isinstance(self.remote_field.model, six.string_types):
-                kwargs['to'] = self.remote_field.model
-            else:
-                kwargs['to'] = '%s.%s' % (self.remote_field.model._meta.app_label, self.remote_field.model._meta.object_name)
+        rel = _remote_field(self)
+        if isinstance(rel.through, six.string_types):
+            kwargs['through'] = rel.through
+        elif not rel.through._meta.auto_created:
+            kwargs['through'] = "%s.%s" % (rel.through._meta.app_label, rel.through._meta.object_name)
+
+        related_model = _related_model(rel)
+        if isinstance(related_model, six.string_types):
+            kwargs['to'] = related_model
         else:
-            if isinstance(self.rel.to, six.string_types):
-                kwargs['to'] = self.rel.to
-            else:
-                kwargs['to'] = '%s.%s' % (self.rel.to._meta.app_label, self.rel.to._meta.object_name)
+            kwargs['to'] = '%s.%s' % (related_model._meta.app_label, related_model._meta.object_name)
 
         return name, path, args, kwargs
 
@@ -356,9 +366,11 @@ class TaggableManager(RelatedField, Field):
             # rel.to renamed to remote_field.model in Django 1.9
             if VERSION >= (1, 9):
                 if isinstance(self.remote_field.model, six.string_types):
-                    def resolve_related_class(field, model, cls):
+                    def resolve_related_class(cls, model, field):
                         field.remote_field.model = model
-                    add_lazy_relation(cls, self, self.remote_field.model, resolve_related_class)
+                    lazy_related_operation(
+                        resolve_related_class, cls, self.remote_field.model, field=self
+                    )
             else:
                 if isinstance(self.rel.to, six.string_types):
                     def resolve_related_class(field, model, cls):
@@ -366,13 +378,22 @@ class TaggableManager(RelatedField, Field):
                     add_lazy_relation(cls, self, self.rel.to, resolve_related_class)
 
             if isinstance(self.through, six.string_types):
-                def resolve_related_class(field, model, cls):
-                    self.through = model
-                    self.rel.through = model
-                    self.post_through_setup(cls)
-                add_lazy_relation(
-                    cls, self, self.through, resolve_related_class
-                )
+                if VERSION >= (1, 9):
+                    def resolve_related_class(cls, model, field):
+                        self.through = model
+                        self.remote_field.through = model
+                        self.post_through_setup(cls)
+                    lazy_related_operation(
+                        resolve_related_class, cls, self.through, field=self
+                    )
+                else:
+                    def resolve_related_class(field, model, cls):
+                        self.through = model
+                        _remote_field(self).through = model
+                        self.post_through_setup(cls)
+                    add_lazy_relation(
+                        cls, self, self.through, resolve_related_class
+                    )
             else:
                 self.post_through_setup(cls)
 
@@ -520,7 +541,7 @@ class TaggableManager(RelatedField, Field):
         opts = self.through._meta
         linkfield = _get_field(self.through, self.m2m_reverse_field_name())
         if direct:
-            join1infos = [PathInfo(self.model._meta, opts, [from_field], self.rel, True, False)]
+            join1infos = [PathInfo(self.model._meta, opts, [from_field], _remote_field(self), True, False)]
             join2infos = linkfield.get_path_info()
         else:
             join1infos = linkfield.get_reverse_path_info()
@@ -574,7 +595,7 @@ def _get_subclasses(model):
     for field in all_fields:
         # Django 1.8 +
         if (not RelatedObject and isinstance(field, OneToOneRel) and
-                getattr(field.field.rel, "parent_link", None)):
+                getattr(_remote_field(field.field), "parent_link", None)):
             subclasses.extend(_get_subclasses(field.related_model))
 
         # < Django 1.8
diff --git a/taggit/utils.py b/taggit/utils.py
index 520ac86..ab9fb37 100644
--- a/taggit/utils.py
+++ b/taggit/utils.py
@@ -16,6 +16,20 @@ def _get_field(model, name):
         return model._meta.get_field(name)
 
 
+def _remote_field(field):
+    if VERSION < (1, 9):
+        return field.rel
+    else:
+        return field.remote_field
+
+
+def _related_model(remote_field):
+    if VERSION >= (1, 9):
+        return remote_field.model
+    else:
+        return remote_field.to
+
+
 def _parse_tags(tagstring):
     """
     Parses tag input, with multiple word input being activated and
diff --git a/tests/migrations/0001_initial.py b/tests/migrations/0001_initial.py
index 85d86c2..c944df6 100644
--- a/tests/migrations/0001_initial.py
+++ b/tests/migrations/0001_initial.py
@@ -54,7 +54,7 @@ class Migration(migrations.Migration):
         migrations.CreateModel(
             name='CustomPKHousePet',
             fields=[
-                ('custompkpet_ptr', models.OneToOneField(parent_link=True, auto_created=True, primary_key=True, serialize=False, to='tests.CustomPKPet', help_text='')),
+                ('custompkpet_ptr', models.OneToOneField(parent_link=True, auto_created=True, primary_key=True, serialize=False, to='tests.CustomPKPet', help_text='', on_delete=models.CASCADE)),
                 ('trained', models.BooleanField(default=False, help_text='')),
             ],
             options={
@@ -82,7 +82,7 @@ class Migration(migrations.Migration):
         migrations.CreateModel(
             name='DirectCustomPKHousePet',
             fields=[
-                ('directcustompkpet_ptr', models.OneToOneField(parent_link=True, auto_created=True, primary_key=True, serialize=False, to='tests.DirectCustomPKPet', help_text='')),
+                ('directcustompkpet_ptr', models.OneToOneField(parent_link=True, auto_created=True, primary_key=True, serialize=False, to='tests.DirectCustomPKPet', help_text='', on_delete=models.CASCADE)),
                 ('trained', models.BooleanField(default=False, help_text='')),
             ],
             options={
@@ -112,7 +112,7 @@ class Migration(migrations.Migration):
         migrations.CreateModel(
             name='DirectHousePet',
             fields=[
-                ('directpet_ptr', models.OneToOneField(parent_link=True, auto_created=True, primary_key=True, serialize=False, to='tests.DirectPet', help_text='')),
+                ('directpet_ptr', models.OneToOneField(parent_link=True, auto_created=True, primary_key=True, serialize=False, to='tests.DirectPet', help_text='', on_delete=models.CASCADE)),
                 ('trained', models.BooleanField(default=False, help_text='')),
             ],
             options={
@@ -183,7 +183,7 @@ class Migration(migrations.Migration):
         migrations.CreateModel(
             name='OfficialHousePet',
             fields=[
-                ('officialpet_ptr', models.OneToOneField(parent_link=True, auto_created=True, primary_key=True, serialize=False, to='tests.OfficialPet', help_text='')),
+                ('officialpet_ptr', models.OneToOneField(parent_link=True, auto_created=True, primary_key=True, serialize=False, to='tests.OfficialPet', help_text='', on_delete=models.CASCADE)),
                 ('trained', models.BooleanField(default=False, help_text='')),
             ],
             options={
@@ -208,8 +208,8 @@ class Migration(migrations.Migration):
             fields=[
                 ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, help_text='', verbose_name='ID')),
                 ('object_id', models.IntegerField(help_text='', verbose_name='Object id', db_index=True)),
-                ('content_type', models.ForeignKey(related_name='tests_officialthroughmodel_tagged_items', verbose_name='Content type', to='contenttypes.ContentType', help_text='')),
-                ('tag', models.ForeignKey(related_name='tagged_items', to='tests.OfficialTag', help_text='')),
+                ('content_type', models.ForeignKey(related_name='tests_officialthroughmodel_tagged_items', verbose_name='Content type', to='contenttypes.ContentType', help_text='', on_delete=models.CASCADE)),
+                ('tag', models.ForeignKey(related_name='tagged_items', to='tests.OfficialTag', help_text='', on_delete=models.CASCADE)),
             ],
             options={
                 'abstract': False,
@@ -228,7 +228,7 @@ class Migration(migrations.Migration):
         migrations.CreateModel(
             name='Child',
             fields=[
-                ('parent_ptr', models.OneToOneField(parent_link=True, auto_created=True, primary_key=True, serialize=False, to='tests.Parent', help_text='')),
+                ('parent_ptr', models.OneToOneField(parent_link=True, auto_created=True, primary_key=True, serialize=False, to='tests.Parent', help_text='', on_delete=models.CASCADE)),
             ],
             options={
             },
@@ -247,7 +247,7 @@ class Migration(migrations.Migration):
         migrations.CreateModel(
             name='HousePet',
             fields=[
-                ('pet_ptr', models.OneToOneField(parent_link=True, auto_created=True, primary_key=True, serialize=False, to='tests.Pet', help_text='')),
+                ('pet_ptr', models.OneToOneField(parent_link=True, auto_created=True, primary_key=True, serialize=False, to='tests.Pet', help_text='', on_delete=models.CASCADE)),
                 ('trained', models.BooleanField(default=False, help_text='')),
             ],
             options={
@@ -271,7 +271,7 @@ class Migration(migrations.Migration):
                 ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, help_text='', verbose_name='ID')),
                 ('object_id', models.CharField(help_text='', max_length=50, verbose_name='Object id', db_index=True)),
                 ('content_type', models.ForeignKey(related_name='tests_taggedcustompk_tagged_items', verbose_name='Content type', to='contenttypes.ContentType', help_text='', on_delete=models.CASCADE)),
-                ('tag', models.ForeignKey(related_name='tests_taggedcustompk_items', to='taggit.Tag', help_text='')),
+                ('tag', models.ForeignKey(related_name='tests_taggedcustompk_items', to='taggit.Tag', help_text='', on_delete=models.CASCADE)),
             ],
             options={
                 'abstract': False,
@@ -282,8 +282,8 @@ class Migration(migrations.Migration):
             name='TaggedCustomPKFood',
             fields=[
                 ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, help_text='', verbose_name='ID')),
-                ('content_object', models.ForeignKey(help_text='', to='tests.DirectCustomPKFood')),
-                ('tag', models.ForeignKey(related_name='tests_taggedcustompkfood_items', to='taggit.Tag', help_text='')),
+                ('content_object', models.ForeignKey(help_text='', to='tests.DirectCustomPKFood', on_delete=models.CASCADE)),
+                ('tag', models.ForeignKey(related_name='tests_taggedcustompkfood_items', to='taggit.Tag', help_text='', on_delete=models.CASCADE)),
             ],
             options={
                 'abstract': False,
@@ -294,8 +294,8 @@ class Migration(migrations.Migration):
             name='TaggedCustomPKPet',
             fields=[
                 ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, help_text='', verbose_name='ID')),
-                ('content_object', models.ForeignKey(help_text='', to='tests.DirectCustomPKPet')),
-                ('tag', models.ForeignKey(related_name='tests_taggedcustompkpet_items', to='taggit.Tag', help_text='')),
+                ('content_object', models.ForeignKey(help_text='', to='tests.DirectCustomPKPet', on_delete=models.CASCADE)),
+                ('tag', models.ForeignKey(related_name='tests_taggedcustompkpet_items', to='taggit.Tag', help_text='', on_delete=models.CASCADE)),
             ],
             options={
                 'abstract': False,
@@ -306,8 +306,8 @@ class Migration(migrations.Migration):
             name='TaggedFood',
             fields=[
                 ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, help_text='', verbose_name='ID')),
-                ('content_object', models.ForeignKey(help_text='', to='tests.DirectFood')),
-                ('tag', models.ForeignKey(related_name='tests_taggedfood_items', to='taggit.Tag', help_text='')),
+                ('content_object', models.ForeignKey(help_text='', to='tests.DirectFood', on_delete=models.CASCADE)),
+                ('tag', models.ForeignKey(related_name='tests_taggedfood_items', to='taggit.Tag', help_text='', on_delete=models.CASCADE)),
             ],
             options={
                 'abstract': False,
@@ -318,8 +318,8 @@ class Migration(migrations.Migration):
             name='TaggedPet',
             fields=[
                 ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, help_text='', verbose_name='ID')),
-                ('content_object', models.ForeignKey(help_text='', to='tests.DirectPet')),
-                ('tag', models.ForeignKey(related_name='tests_taggedpet_items', to='taggit.Tag', help_text='')),
+                ('content_object', models.ForeignKey(help_text='', to='tests.DirectPet', on_delete=models.CASCADE)),
+                ('tag', models.ForeignKey(related_name='tests_taggedpet_items', to='taggit.Tag', help_text='', on_delete=models.CASCADE)),
             ],
             options={
                 'abstract': False,
@@ -330,8 +330,8 @@ class Migration(migrations.Migration):
             name='Through1',
             fields=[
                 ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, help_text='', verbose_name='ID')),
-                ('content_object', models.ForeignKey(help_text='', to='tests.MultipleTags')),
-                ('tag', models.ForeignKey(related_name='tests_through1_items', to='taggit.Tag', help_text='')),
+                ('content_object', models.ForeignKey(help_text='', to='tests.MultipleTags', on_delete=models.CASCADE)),
+                ('tag', models.ForeignKey(related_name='tests_through1_items', to='taggit.Tag', help_text='', on_delete=models.CASCADE)),
             ],
             options={
                 'abstract': False,
@@ -342,8 +342,8 @@ class Migration(migrations.Migration):
             name='Through2',
             fields=[
                 ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, help_text='', verbose_name='ID')),
-                ('content_object', models.ForeignKey(help_text='', to='tests.MultipleTags')),
-                ('tag', models.ForeignKey(related_name='tests_through2_items', to='taggit.Tag', help_text='')),
+                ('content_object', models.ForeignKey(help_text='', to='tests.MultipleTags', on_delete=models.CASCADE)),
+                ('tag', models.ForeignKey(related_name='tests_through2_items', to='taggit.Tag', help_text='', on_delete=models.CASCADE)),
             ],
             options={
                 'abstract': False,
@@ -355,8 +355,8 @@ class Migration(migrations.Migration):
             fields=[
                 ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, help_text='', verbose_name='ID')),
                 ('object_id', models.IntegerField(help_text='', verbose_name='Object id', db_index=True)),
-                ('content_type', models.ForeignKey(related_name='tests_throughgfk_tagged_items', verbose_name='Content type', to='contenttypes.ContentType', help_text='')),
-                ('tag', models.ForeignKey(related_name='tagged_items', to='taggit.Tag', help_text='')),
+                ('content_type', models.ForeignKey(related_name='tests_throughgfk_tagged_items', verbose_name='Content type', to='contenttypes.ContentType', help_text='', on_delete=models.CASCADE)),
+                ('tag', models.ForeignKey(related_name='tagged_items', to='taggit.Tag', help_text='', on_delete=models.CASCADE)),
             ],
             options={
                 'abstract': False,
diff --git a/tests/models.py b/tests/models.py
index db1d96c..71a92fd 100644
--- a/tests/models.py
+++ b/tests/models.py
@@ -10,11 +10,11 @@ from taggit.models import (CommonGenericTaggedItemBase, GenericTaggedItemBase,
 
 # Ensure that two TaggableManagers with custom through model are allowed.
 class Through1(TaggedItemBase):
-    content_object = models.ForeignKey('MultipleTags')
+    content_object = models.ForeignKey('MultipleTags', on_delete=models.CASCADE)
 
 
 class Through2(TaggedItemBase):
-    content_object = models.ForeignKey('MultipleTags')
+    content_object = models.ForeignKey('MultipleTags', on_delete=models.CASCADE)
 
 
 class MultipleTags(models.Model):
@@ -23,7 +23,7 @@ class MultipleTags(models.Model):
 
 # Ensure that two TaggableManagers with GFK via different through models are allowed.
 class ThroughGFK(GenericTaggedItemBase):
-    tag = models.ForeignKey(Tag, related_name='tagged_items')
+    tag = models.ForeignKey(Tag, related_name='tagged_items', on_delete=models.CASCADE)
 
 class MultipleTagsGFK(models.Model):
     tags1 = TaggableManager(related_name='tagsgfk1')
@@ -56,11 +56,11 @@ class HousePet(Pet):
 # Test direct-tagging with custom through model
 
 class TaggedFood(TaggedItemBase):
-    content_object = models.ForeignKey('DirectFood')
+    content_object = models.ForeignKey('DirectFood', on_delete=models.CASCADE)
 
 
 class TaggedPet(TaggedItemBase):
-    content_object = models.ForeignKey('DirectPet')
+    content_object = models.ForeignKey('DirectPet', on_delete=models.CASCADE)
 
 
 @python_2_unicode_compatible
@@ -90,10 +90,10 @@ class DirectHousePet(DirectPet):
 # Test custom through model to model with custom PK
 
 class TaggedCustomPKFood(TaggedItemBase):
-    content_object = models.ForeignKey('DirectCustomPKFood')
+    content_object = models.ForeignKey('DirectCustomPKFood', on_delete=models.CASCADE)
 
 class TaggedCustomPKPet(TaggedItemBase):
-    content_object = models.ForeignKey('DirectCustomPKPet')
+    content_object = models.ForeignKey('DirectCustomPKPet', on_delete=models.CASCADE)
 
 @python_2_unicode_compatible
 class DirectCustomPKFood(models.Model):
@@ -148,7 +148,7 @@ class OfficialTag(TagBase):
     official = models.BooleanField(default=False)
 
 class OfficialThroughModel(GenericTaggedItemBase):
-    tag = models.ForeignKey(OfficialTag, related_name="tagged_items")
+    tag = models.ForeignKey(OfficialTag, related_name="tagged_items", on_delete=models.CASCADE)
 
 @python_2_unicode_compatible
 class OfficialFood(models.Model):
diff --git a/tests/tests.py b/tests/tests.py
index f57535d..9e4d2c3 100644
--- a/tests/tests.py
+++ b/tests/tests.py
@@ -1,5 +1,7 @@
 from __future__ import absolute_import, unicode_literals
 
+import sys
+import warnings
 from unittest import TestCase as UnitTestCase
 
 import django
@@ -10,7 +12,6 @@ from django.core.management import call_command
 from django.db import connection, models
 from django.test import TestCase, TransactionTestCase
 from django.test.utils import override_settings
-from django.utils import six
 from django.utils.encoding import force_text
 
 from .forms import (CustomPKFoodForm, DirectCustomPKFoodForm, DirectFoodForm,
@@ -26,7 +27,7 @@ from .models import (Article, Child, CustomManager, CustomPKFood,
 from taggit.managers import _model_name, _TaggableManager, TaggableManager
 from taggit.models import Tag, TaggedItem
 
-from taggit.utils import edit_string_for_tags, parse_tags
+from taggit.utils import edit_string_for_tags, parse_tags, _remote_field, _related_model
 
 try:
     from unittest import skipIf, skipUnless
@@ -56,7 +57,22 @@ class BaseTaggingTest(object):
         return form_str
 
     def assert_form_renders(self, form, html):
-        self.assertHTMLEqual(str(form), self._get_form_str(html))
+        # Django causes a DeprecationWarning on Python 3.3, 3.4
+        if (3, 3) <= sys.version_info < (3, 5):
+            with warnings.catch_warnings(record=True):
+                self.assertHTMLEqual(str(form), self._get_form_str(html))
+        else:
+            self.assertHTMLEqual(str(form), self._get_form_str(html))
+
+
+# assertRaisesRegexp is deprecated in favour of assertRaisesRegex in recent versions of unittest,
+# but not present in older versions. As Django bundles a version of unittest, this means that
+# different versions of Django use different versions of unittest. The following monkeypatch means
+# that every version can use the assertRaisesRegex to avioid the deprecation warnings
+if not hasattr(TestCase, 'assertRaisesRegex'):
+    def assertRaisesRegex(self, expected_exception, expected_regex, *args, **kwargs):
+        return self.assertRaisesRegexp(expected_exception, expected_regex, *args, **kwargs)
+    BaseTaggingTest.assertRaisesRegex = assertRaisesRegex
 
 
 class BaseTaggingTestCase(TestCase, BaseTaggingTest):
@@ -96,7 +112,7 @@ class TagModelTestCase(BaseTaggingTransactionTestCase):
     def test_integers(self):
         """Adding an integer as a tag should raise a ValueError (#237)."""
         apple = self.food_model.objects.create(name="apple")
-        with self.assertRaisesRegexp(ValueError, (
+        with self.assertRaisesRegex(ValueError, (
                 r"Cannot add 1 \(<(type|class) 'int'>\). "
                 r"Expected <class 'django.db.models.base.ModelBase'> or str.")):
             apple.tags.add(1)
@@ -148,6 +164,12 @@ class TaggableManagerTestCase(BaseTaggingTestCase):
             sort=False
         )
 
+        self.assert_tags_equal(
+            self.food_model.tags.most_common(min_count=2),
+            ['green'],
+            sort=False
+        )
+
         apple.tags.remove('green')
         self.assert_tags_equal(apple.tags.all(), ['red'])
         self.assert_tags_equal(self.food_model.tags.all(), ['green', 'red'])
@@ -342,15 +364,24 @@ class TaggableManagerTestCase(BaseTaggingTestCase):
     def test_field_api(self):
         # Check if tag field, which simulates m2m, has django-like api.
         field = self.food_model._meta.get_field('tags')
-        self.assertTrue(hasattr(field, 'rel'))
-        self.assertTrue(hasattr(field.rel, 'to'))
-        self.assertTrue(hasattr(field, 'related'))
+        if django.VERSION >= (1, 9):
+            self.assertTrue(hasattr(field, 'remote_field'))
+            self.assertTrue(hasattr(field.remote_field, 'model'))
+        elif django.VERSION >= (1, 8):
+            self.assertTrue(hasattr(field, 'rel'))
+            self.assertTrue(hasattr(field.rel, 'to'))
+        else:
+            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, 9):
+            self.assertEqual(self.food_model, field.model)
+            self.assertEqual(self.tag_model, _remote_field(field).model)
         if django.VERSION >= (1, 8):
             self.assertEqual(self.food_model, field.model)
-            self.assertEqual(self.tag_model, field.related.model)
+            self.assertEqual(self.tag_model, _remote_field(field).model)
         else:
             self.assertEqual(self.food_model, field.related.model)
 
@@ -643,8 +674,8 @@ class DeconstructTestCase(UnitTestCase):
         instance = TaggableManager(through=OfficialThroughModel, to='dummy.To')
         name, path, args, kwargs = instance.deconstruct()
         new_instance = TaggableManager(*args, **kwargs)
-        self.assertEqual('tests.OfficialThroughModel', new_instance.rel.through)
-        self.assertEqual('dummy.To', new_instance.rel.to)
+        self.assertEqual('tests.OfficialThroughModel', _remote_field(new_instance).through)
+        self.assertEqual('dummy.To', _related_model(_remote_field(new_instance)))
 
 
 @skipUnless(django.VERSION < (1, 7), "test only applies to 1.6 and below")
@@ -666,12 +697,12 @@ class InheritedPrefetchTests(TestCase):
 
         child = Child.objects.get()
         no_prefetch_tags = child.tags.all()
-        self.assertEquals(4, no_prefetch_tags.count())
+        self.assertEqual(4, no_prefetch_tags.count())
         child = Child.objects.prefetch_related('tags').get()
         prefetch_tags = child.tags.all()
-        self.assertEquals(4, prefetch_tags.count())
-        self.assertEquals(set([t.name for t in no_prefetch_tags]),
-                          set([t.name for t in prefetch_tags]))
+        self.assertEqual(4, prefetch_tags.count())
+        self.assertEqual(set([t.name for t in no_prefetch_tags]),
+                         set([t.name for t in prefetch_tags]))
 
 
 class DjangoCheckTests(UnitTestCase):
@@ -680,4 +711,4 @@ class DjangoCheckTests(UnitTestCase):
         if django.VERSION >= (1, 6):
             call_command('check', tag=['models'])
         else:
-                    call_command('validate')
+            call_command('validate')
diff --git a/tox.ini b/tox.ini
index 7dd3b45..46f975f 100644
--- a/tox.ini
+++ b/tox.ini
@@ -109,3 +109,15 @@ basepython = python3.4
 deps =
 	{[testenv]deps}
 	{[testenv]deps19}
+
+[testenv:py35-1.8.x]
+basepython = python3.5
+deps =
+	{[testenv]deps}
+	{[testenv]deps18}
+
+[testenv:py35-1.9.x]
+basepython = python3.5
+deps =
+	{[testenv]deps}
+	{[testenv]deps19}

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/collab-maint/django-taggit.git



More information about the Python-modules-commits mailing list