[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