[Python-modules-commits] [django-taggit] 01/04: Imported Upstream version 0.12.2

Michal Cihar nijel at moszumanska.debian.org
Thu Sep 25 07:23:05 UTC 2014


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

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

commit 8c9e96c5e394694eae24866f0348bb4203bf8396
Author: Michal Čihař <michal at cihar.com>
Date:   Thu Sep 25 09:18:36 2014 +0200

    Imported Upstream version 0.12.2
---
 CHANGELOG.txt                     |  4 ++
 PKG-INFO                          |  2 +-
 django_taggit.egg-info/PKG-INFO   |  2 +-
 setup.cfg                         |  6 +++
 setup.py                          |  2 +-
 taggit/__init__.py                |  2 +-
 taggit/forms.py                   | 11 +++--
 taggit/managers.py                | 77 +++++++++++++++++-------------
 taggit/migrations/0001_initial.py |  7 +--
 taggit/models.py                  | 16 ++++---
 taggit/utils.py                   |  2 +-
 taggit/views.py                   |  3 +-
 tests/forms.py                    |  7 ++-
 tests/migrations/0001_initial.py  | 52 +++++++++++++++------
 tests/models.py                   | 12 ++++-
 tests/tests.py                    | 98 +++++++++++++++++++++++++--------------
 tox.ini                           |  2 +-
 17 files changed, 196 insertions(+), 109 deletions(-)

diff --git a/CHANGELOG.txt b/CHANGELOG.txt
index 856d027..7760cbb 100644
--- a/CHANGELOG.txt
+++ b/CHANGELOG.txt
@@ -1,6 +1,10 @@
 Changelog
 =========
 
+0.12.2 (21.09.2014)
+~~~~~~~~~~~~~~~~~~~
+ * Fixed 1.7 migrations.
+
 0.12.1 (10.08.2014)
 ~~~~~~~~~~~~~~~~~~~
  * Final (hopefully) fixes for the upcoming Django 1.7 release.
diff --git a/PKG-INFO b/PKG-INFO
index 7ca2a1c..b672158 100644
--- a/PKG-INFO
+++ b/PKG-INFO
@@ -1,6 +1,6 @@
 Metadata-Version: 1.1
 Name: django-taggit
-Version: 0.12.1
+Version: 0.12.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 7ca2a1c..b672158 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.12.1
+Version: 0.12.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/setup.cfg b/setup.cfg
index a182425..fafd3e2 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -4,6 +4,12 @@ license-file = LICENSE
 [wheel]
 universal = 1
 
+[flake8]
+ignore = E501,E302
+
+[isort]
+forced_separate = tests,taggit
+
 [egg_info]
 tag_build = 
 tag_date = 0
diff --git a/setup.py b/setup.py
index dbcfc51..f994789 100644
--- a/setup.py
+++ b/setup.py
@@ -7,7 +7,7 @@ f.close()
 
 setup(
     name='django-taggit',
-    version='0.12.1',
+    version='0.12.2',
     description='django-taggit is a reusable Django application for simple tagging.',
     long_description=readme,
     author='Alex Gaynor',
diff --git a/taggit/__init__.py b/taggit/__init__.py
index ef67568..00f81bf 100644
--- a/taggit/__init__.py
+++ b/taggit/__init__.py
@@ -1 +1 @@
-VERSION = (0, 12, 1)
+VERSION = (0, 12, 2)
diff --git a/taggit/forms.py b/taggit/forms.py
index cb372f2..88ac842 100644
--- a/taggit/forms.py
+++ b/taggit/forms.py
@@ -1,18 +1,20 @@
 from __future__ import unicode_literals
 
 from django import forms
-from django.utils.translation import ugettext as _
 from django.utils import six
+from django.utils.translation import ugettext as _
 
-from taggit.utils import parse_tags, edit_string_for_tags
+from taggit.utils import edit_string_for_tags, parse_tags
 
 
 class TagWidget(forms.TextInput):
     def render(self, name, value, attrs=None):
         if value is not None and not isinstance(value, six.string_types):
-            value = edit_string_for_tags([o.tag for o in value.select_related("tag")])
+            value = edit_string_for_tags([
+                o.tag for o in value.select_related("tag")])
         return super(TagWidget, self).render(name, value, attrs)
 
+
 class TagField(forms.CharField):
     widget = TagWidget
 
@@ -21,4 +23,5 @@ class TagField(forms.CharField):
         try:
             return parse_tags(value)
         except ValueError:
-            raise forms.ValidationError(_("Please provide a comma-separated list of tags."))
+            raise forms.ValidationError(
+                _("Please provide a comma-separated list of tags."))
diff --git a/taggit/managers.py b/taggit/managers.py
index 9e1b8c4..2bab18f 100644
--- a/taggit/managers.py
+++ b/taggit/managers.py
@@ -1,28 +1,32 @@
 from __future__ import unicode_literals
+
 from operator import attrgetter
 
 from django import VERSION
-try:
-    from django.contrib.contenttypes.fields import GenericRelation
-except ImportError:  # django < 1.7
-    from django.contrib.contenttypes.generic import GenericRelation
 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 ManyToManyRel, RelatedField, add_lazy_relation
+from django.db.models.fields.related import (add_lazy_relation, ManyToManyRel,
+                                             RelatedField)
 from django.db.models.related import RelatedObject
+from django.utils import six
 from django.utils.text import capfirst
 from django.utils.translation import ugettext_lazy as _
-from django.utils import six
+
+from taggit.forms import TagField
+from taggit.models import GenericTaggedItemBase, TaggedItem
+from taggit.utils import require_instance_manager
+
+try:
+    from django.contrib.contenttypes.fields import GenericRelation
+except ImportError:  # django < 1.7
+    from django.contrib.contenttypes.generic import GenericRelation
 
 try:
     from django.db.models.related import PathInfo
 except ImportError:
     pass  # PathInfo is not used on Django < 1.6
 
-from taggit.forms import TagField
-from taggit.models import TaggedItem, GenericTaggedItemBase
-from taggit.utils import require_instance_manager
 
 
 def _model_name(model):
@@ -102,7 +106,7 @@ class _TaggableManager(models.Manager):
                      else 'content_object')
         fk = self.through._meta.get_field(fieldname)
         query = {
-            '%s__%s__in' % (self.through.tag_relname(), fk.name) :
+            '%s__%s__in' % (self.through.tag_relname(), fk.name):
                 set(obj._get_pk_val() for obj in instances)
         }
         join_table = self.through._meta.db_table
@@ -110,13 +114,13 @@ class _TaggableManager(models.Manager):
         connection = connections[db]
         qn = connection.ops.quote_name
         qs = self.get_queryset().using(db)._next_is_sticky().filter(**query).extra(
-            select = {
-                '_prefetch_related_val' : '%s.%s' % (qn(join_table), qn(source_col))
+            select={
+                '_prefetch_related_val': '%s.%s' % (qn(join_table), qn(source_col))
             }
         )
         return (qs,
                 attrgetter('_prefetch_related_val'),
-                attrgetter(instance._meta.pk.name),
+                lambda obj: obj._get_pk_val(),
                 False,
                 self.prefetch_cache_name)
 
@@ -129,12 +133,17 @@ class _TaggableManager(models.Manager):
 
     @require_instance_manager
     def add(self, *tags):
-        str_tags = set([
-            t
-            for t in tags
-            if not isinstance(t, self.through.tag_model())
-        ])
-        tag_objs = set(tags) - str_tags
+        str_tags = set()
+        tag_objs = set()
+        for t in tags:
+            if isinstance(t, self.through.tag_model()):
+                tag_objs.add(t)
+            elif isinstance(t, six.string_types):
+                str_tags.add(t)
+            else:
+                raise ValueError("Cannot add {0} ({1}). Expected {2} or str.".format(
+                    t, type(t), type(self.through.tag_model())))
+
         # If str_tags has 0 elements Django actually optimizes that to not do a
         # query.  Malcolm is very smart.
         existing = self.through.tag_model().objects.filter(
@@ -220,10 +229,12 @@ class _TaggableManager(models.Manager):
 class TaggableManager(RelatedField, Field):
     _related_name_counter = 0
 
-    def __init__(self, verbose_name=_("Tags"), help_text=_("A comma-separated list of tags."),
-            through=None, blank=False, related_name=None, to=None,
-            manager=_TaggableManager):
-        Field.__init__(self, verbose_name=verbose_name, help_text=help_text, blank=blank, null=True, serialize=False)
+    def __init__(self, verbose_name=_("Tags"),
+                 help_text=_("A comma-separated list of tags."),
+                 through=None, blank=False, related_name=None, to=None,
+                 manager=_TaggableManager):
+        Field.__init__(self, verbose_name=verbose_name, help_text=help_text,
+                       blank=blank, null=True, serialize=False)
         self.through = through or TaggedItem
         self.rel = TaggableRel(self, related_name, self.through, to=to)
         self.swappable = False
@@ -233,12 +244,12 @@ class TaggableManager(RelatedField, Field):
     def __get__(self, instance, model):
         if instance is not None and instance.pk is None:
             raise ValueError("%s objects need to have a primary key value "
-                "before you can access their tags." % model.__name__)
+                             "before you can access their tags." % model.__name__)
         manager = self.manager(
             through=self.through,
             model=model,
             instance=instance,
-            prefetch_cache_name = self.name
+            prefetch_cache_name=self.name
         )
         return manager
 
@@ -287,7 +298,6 @@ class TaggableManager(RelatedField, Field):
             else:
                 self.post_through_setup(cls)
 
-
     def __lt__(self, other):
         """
         Required contribute_to_class as Django uses bisect
@@ -364,7 +374,7 @@ class TaggableManager(RelatedField, Field):
     def extra_filters(self, pieces, pos, negate):
         if negate or not self.use_gfk:
             return []
-        prefix = "__".join(["tagged_items"] + pieces[:pos-2])
+        prefix = "__".join(["tagged_items"] + pieces[:pos - 2])
         get = ContentType.objects.get_for_model
         cts = [get(obj) for obj in _get_subclasses(self.model)]
         if len(cts) == 1:
@@ -378,13 +388,18 @@ class TaggableManager(RelatedField, Field):
         else:
             alias_to_join = lhs_alias
         extra_col = self.through._meta.get_field_by_name('content_type')[0].column
-        content_type_ids = [ContentType.objects.get_for_model(subclass).pk for subclass in _get_subclasses(self.model)]
+        content_type_ids = [ContentType.objects.get_for_model(subclass).pk for
+                            subclass in _get_subclasses(self.model)]
         if len(content_type_ids) == 1:
             content_type_id = content_type_ids[0]
-            extra_where = " AND %s.%s = %%s" % (qn(alias_to_join), qn(extra_col))
+            extra_where = " AND %s.%s = %%s" % (qn(alias_to_join),
+                                                qn(extra_col))
             params = [content_type_id]
         else:
-            extra_where = " AND %s.%s IN (%s)" % (qn(alias_to_join), qn(extra_col), ','.join(['%s']*len(content_type_ids)))
+            extra_where = " AND %s.%s IN (%s)" % (qn(alias_to_join),
+                                                  qn(extra_col),
+                                                  ','.join(['%s'] *
+                                                           len(content_type_ids)))
             params = content_type_ids
         return extra_where, params
 
@@ -461,7 +476,7 @@ def _get_subclasses(model):
     for f in model._meta.get_all_field_names():
         field = model._meta.get_field_by_name(f)[0]
         if (isinstance(field, RelatedObject) and
-            getattr(field.field.rel, "parent_link", None)):
+                getattr(field.field.rel, "parent_link", None)):
             subclasses.extend(_get_subclasses(field.model))
     return subclasses
 
diff --git a/taggit/migrations/0001_initial.py b/taggit/migrations/0001_initial.py
index 616ec09..564fb3c 100644
--- a/taggit/migrations/0001_initial.py
+++ b/taggit/migrations/0001_initial.py
@@ -1,5 +1,6 @@
-# encoding: utf8
+# -*- coding: utf-8 -*-
 from __future__ import unicode_literals
+
 from django.db import models, migrations
 
 
@@ -27,9 +28,9 @@ class Migration(migrations.Migration):
             name='TaggedItem',
             fields=[
                 ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
-                ('tag', models.ForeignKey(to='taggit.Tag', to_field='id')),
                 ('object_id', models.IntegerField(verbose_name='Object id', db_index=True)),
-                ('content_type', models.ForeignKey(to='contenttypes.ContentType', to_field='id', verbose_name='Content type')),
+                ('content_type', models.ForeignKey(related_name='taggit_taggeditem_tagged_items', verbose_name='Content type', to='contenttypes.ContentType')),
+                ('tag', models.ForeignKey(related_name='taggit_taggeditem_items', to='taggit.Tag')),
             ],
             options={
                 'verbose_name': 'Tagged Item',
diff --git a/taggit/models.py b/taggit/models.py
index 094df6e..e5f5aea 100644
--- a/taggit/models.py
+++ b/taggit/models.py
@@ -1,15 +1,17 @@
 from __future__ import unicode_literals
 
 from django.contrib.contenttypes.models import ContentType
+from django.db import IntegrityError, models, transaction
+from django.db.models.query import QuerySet
+from django.template.defaultfilters import slugify as default_slugify
+from django.utils.encoding import python_2_unicode_compatible
+from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import ugettext
+
 try:
     from django.contrib.contenttypes.fields import GenericForeignKey
 except ImportError:  # django < 1.7
     from django.contrib.contenttypes.generic import GenericForeignKey
-from django.db import models, IntegrityError, transaction
-from django.db.models.query import QuerySet
-from django.template.defaultfilters import slugify as default_slugify
-from django.utils.translation import ugettext_lazy as _, ugettext
-from django.utils.encoding import python_2_unicode_compatible
 
 
 try:
@@ -59,7 +61,7 @@ class TagBase(models.Model):
             except IntegrityError:
                 pass
             # Now try to find existing slugs with similar names
-            slugs = set(Tag.objects.filter(slug__startswith=self.slug)\
+            slugs = set(Tag.objects.filter(slug__startswith=self.slug)
                                    .values_list('slug', flat=True))
             i = 1
             while True:
@@ -145,7 +147,7 @@ class GenericTaggedItemBase(ItemBase):
     content_object = GenericForeignKey()
 
     class Meta:
-        abstract=True
+        abstract = True
 
     @classmethod
     def lookup_kwargs(cls, instance):
diff --git a/taggit/utils.py b/taggit/utils.py
index 997c4f0..162b7bd 100644
--- a/taggit/utils.py
+++ b/taggit/utils.py
@@ -1,8 +1,8 @@
 from __future__ import unicode_literals
 
+from django.utils import six
 from django.utils.encoding import force_text
 from django.utils.functional import wraps
-from django.utils import six
 
 
 def parse_tags(tagstring):
diff --git a/taggit/views.py b/taggit/views.py
index 68c06db..5b6c0c4 100644
--- a/taggit/views.py
+++ b/taggit/views.py
@@ -4,7 +4,7 @@ from django.contrib.contenttypes.models import ContentType
 from django.shortcuts import get_object_or_404
 from django.views.generic.list import ListView
 
-from taggit.models import TaggedItem, Tag
+from taggit.models import Tag, TaggedItem
 
 
 def tagged_object_list(request, slug, queryset, **kwargs):
@@ -18,4 +18,3 @@ def tagged_object_list(request, slug, queryset, **kwargs):
         kwargs["extra_context"] = {}
     kwargs["extra_context"]["tag"] = tag
     return ListView.as_view(request, qs, **kwargs)
-
diff --git a/tests/forms.py b/tests/forms.py
index 1200792..4c6baca 100644
--- a/tests/forms.py
+++ b/tests/forms.py
@@ -1,12 +1,11 @@
-from __future__ import unicode_literals, absolute_import
+from __future__ import absolute_import, unicode_literals
 
 from django import forms, VERSION
 
-from .models import Food, DirectFood, CustomPKFood, OfficialFood
-
+from .models import CustomPKFood, DirectFood, Food, OfficialFood
 
 fields = None
-if VERSION >= (1,6):
+if VERSION >= (1, 6):
     fields = '__all__'
 
 
diff --git a/tests/migrations/0001_initial.py b/tests/migrations/0001_initial.py
index 3c9d74d..46743af 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(auto_created=True, primary_key=True, serialize=False, to='tests.CustomPKPet')),
+                ('custompkpet_ptr', models.OneToOneField(parent_link=True, auto_created=True, primary_key=True, serialize=False, to='tests.CustomPKPet')),
                 ('trained', models.BooleanField(default=False)),
             ],
             options={
@@ -84,7 +84,7 @@ class Migration(migrations.Migration):
         migrations.CreateModel(
             name='DirectHousePet',
             fields=[
-                ('directpet_ptr', models.OneToOneField(auto_created=True, primary_key=True, serialize=False, to='tests.DirectPet')),
+                ('directpet_ptr', models.OneToOneField(parent_link=True, auto_created=True, primary_key=True, serialize=False, to='tests.DirectPet')),
                 ('trained', models.BooleanField(default=False)),
             ],
             options={
@@ -155,7 +155,7 @@ class Migration(migrations.Migration):
         migrations.CreateModel(
             name='OfficialHousePet',
             fields=[
-                ('officialpet_ptr', models.OneToOneField(auto_created=True, primary_key=True, serialize=False, to='tests.OfficialPet')),
+                ('officialpet_ptr', models.OneToOneField(parent_link=True, auto_created=True, primary_key=True, serialize=False, to='tests.OfficialPet')),
                 ('trained', models.BooleanField(default=False)),
             ],
             options={
@@ -180,8 +180,8 @@ class Migration(migrations.Migration):
             fields=[
                 ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
                 ('object_id', models.IntegerField(verbose_name='Object id', db_index=True)),
-                ('content_type', models.ForeignKey(verbose_name='Content type', to='contenttypes.ContentType')),
-                ('tag', models.ForeignKey(to='tests.OfficialTag')),
+                ('content_type', models.ForeignKey(related_name='tests_officialthroughmodel_tagged_items', verbose_name='Content type', to='contenttypes.ContentType')),
+                ('tag', models.ForeignKey(related_name='tagged_items', to='tests.OfficialTag')),
             ],
             options={
                 'abstract': False,
@@ -201,6 +201,30 @@ class Migration(migrations.Migration):
             preserve_default=True,
         ),
         migrations.CreateModel(
+            name='Parent',
+            fields=[
+                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
+            ],
+            options={
+            },
+            bases=(models.Model,),
+        ),
+        migrations.CreateModel(
+            name='Child',
+            fields=[
+                ('parent_ptr', models.OneToOneField(parent_link=True, auto_created=True, primary_key=True, serialize=False, to='tests.Parent')),
+            ],
+            options={
+            },
+            bases=('tests.parent',),
+        ),
+        migrations.AddField(
+            model_name='parent',
+            name='tags',
+            field=taggit.managers.TaggableManager(to='taggit.Tag', through='taggit.TaggedItem', help_text='A comma-separated list of tags.', verbose_name='Tags'),
+            preserve_default=True,
+        ),
+        migrations.CreateModel(
             name='Pet',
             fields=[
                 ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
@@ -213,7 +237,7 @@ class Migration(migrations.Migration):
         migrations.CreateModel(
             name='HousePet',
             fields=[
-                ('pet_ptr', models.OneToOneField(auto_created=True, primary_key=True, serialize=False, to='tests.Pet')),
+                ('pet_ptr', models.OneToOneField(parent_link=True, auto_created=True, primary_key=True, serialize=False, to='tests.Pet')),
                 ('trained', models.BooleanField(default=False)),
             ],
             options={
@@ -262,7 +286,7 @@ class Migration(migrations.Migration):
         migrations.AddField(
             model_name='taggedcustompkfood',
             name='tag',
-            field=models.ForeignKey(to='taggit.Tag'),
+            field=models.ForeignKey(related_name='tests_taggedcustompkfood_items', to='taggit.Tag'),
             preserve_default=True,
         ),
         migrations.CreateModel(
@@ -290,7 +314,7 @@ class Migration(migrations.Migration):
         migrations.AddField(
             model_name='taggedcustompkpet',
             name='tag',
-            field=models.ForeignKey(to='taggit.Tag'),
+            field=models.ForeignKey(related_name='tests_taggedcustompkpet_items', to='taggit.Tag'),
             preserve_default=True,
         ),
         migrations.CreateModel(
@@ -318,7 +342,7 @@ class Migration(migrations.Migration):
         migrations.AddField(
             model_name='taggedfood',
             name='tag',
-            field=models.ForeignKey(to='taggit.Tag'),
+            field=models.ForeignKey(related_name='tests_taggedfood_items', to='taggit.Tag'),
             preserve_default=True,
         ),
         migrations.CreateModel(
@@ -346,7 +370,7 @@ class Migration(migrations.Migration):
         migrations.AddField(
             model_name='taggedpet',
             name='tag',
-            field=models.ForeignKey(to='taggit.Tag'),
+            field=models.ForeignKey(related_name='tests_taggedpet_items', to='taggit.Tag'),
             preserve_default=True,
         ),
         migrations.CreateModel(
@@ -374,7 +398,7 @@ class Migration(migrations.Migration):
         migrations.AddField(
             model_name='through1',
             name='tag',
-            field=models.ForeignKey(to='taggit.Tag'),
+            field=models.ForeignKey(related_name='tests_through1_items', to='taggit.Tag'),
             preserve_default=True,
         ),
         migrations.CreateModel(
@@ -402,7 +426,7 @@ class Migration(migrations.Migration):
         migrations.AddField(
             model_name='through2',
             name='tag',
-            field=models.ForeignKey(to='taggit.Tag'),
+            field=models.ForeignKey(related_name='tests_through2_items', to='taggit.Tag'),
             preserve_default=True,
         ),
         migrations.CreateModel(
@@ -410,8 +434,8 @@ class Migration(migrations.Migration):
             fields=[
                 ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
                 ('object_id', models.IntegerField(verbose_name='Object id', db_index=True)),
-                ('content_type', models.ForeignKey(verbose_name='Content type', to='contenttypes.ContentType')),
-                ('tag', models.ForeignKey(to='taggit.Tag')),
+                ('content_type', models.ForeignKey(related_name='tests_throughgfk_tagged_items', verbose_name='Content type', to='contenttypes.ContentType')),
+                ('tag', models.ForeignKey(related_name='tagged_items', to='taggit.Tag')),
             ],
             options={
                 'abstract': False,
diff --git a/tests/models.py b/tests/models.py
index d88d65a..f20cc38 100644
--- a/tests/models.py
+++ b/tests/models.py
@@ -4,8 +4,8 @@ from django.db import models
 from django.utils.encoding import python_2_unicode_compatible
 
 from taggit.managers import TaggableManager
-from taggit.models import (TaggedItemBase, GenericTaggedItemBase, TaggedItem,
-    TagBase, Tag)
+from taggit.models import (GenericTaggedItemBase, Tag, TagBase, TaggedItem,
+                           TaggedItemBase)
 
 
 # Ensure that two TaggableManagers with custom through model are allowed.
@@ -192,3 +192,11 @@ class CustomManager(models.Model):
             pass
 
     tags = TaggableManager(manager=Foo)
+
+
+class Parent(models.Model):
+    tags = TaggableManager()
+
+
+class Child(Parent):
+    pass
diff --git a/tests/tests.py b/tests/tests.py
index 10710c1..791ac77 100644
--- a/tests/tests.py
+++ b/tests/tests.py
@@ -1,31 +1,32 @@
-from __future__ import unicode_literals, absolute_import
+from __future__ import absolute_import, unicode_literals
 
 from unittest import TestCase as UnitTestCase
-try:
-    from unittest import skipIf, skipUnless
-except:
-    from django.utils.unittest import skipIf, skipUnless
 
 import django
-from django.conf import settings
-from django.core.exceptions import ImproperlyConfigured, ValidationError
+from django.contrib.contenttypes.models import ContentType
 from django.core import serializers
-from django.db import connection
+from django.core.exceptions import ImproperlyConfigured, ValidationError
 from django.test import TestCase, TransactionTestCase
-from django.utils import six
 from django.utils.encoding import force_text
 
-from django.contrib.contenttypes.models import ContentType
+from .forms import CustomPKFoodForm, DirectFoodForm, FoodForm, OfficialFoodForm
+from .models import (Article, Child, CustomManager, CustomPKFood,
+                     CustomPKHousePet, CustomPKPet, DirectFood,
+                     DirectHousePet, DirectPet, Food, HousePet, Movie,
+                     OfficialFood, OfficialHousePet, OfficialPet,
+                     OfficialTag, OfficialThroughModel, Pet, Photo,
+                     TaggedCustomPKFood, TaggedCustomPKPet, TaggedFood,
+                     TaggedPet)
 
-from taggit.managers import TaggableManager, _TaggableManager, _model_name
+from taggit.managers import _model_name, _TaggableManager, TaggableManager
 from taggit.models import Tag, TaggedItem
-from .forms import (FoodForm, DirectFoodForm, CustomPKFoodForm,
-    OfficialFoodForm)
-from .models import (Food, Pet, HousePet, DirectFood, DirectPet,
-    DirectHousePet, TaggedFood, CustomPKFood, CustomPKPet, CustomPKHousePet,
-    TaggedCustomPKFood, OfficialFood, OfficialPet, OfficialHousePet,
-    OfficialThroughModel, OfficialTag, Photo, Movie, Article, CustomManager)
-from taggit.utils import parse_tags, edit_string_for_tags
+
+from taggit.utils import edit_string_for_tags, parse_tags
+
+try:
+    from unittest import skipIf, skipUnless
+except ImportError:
+    from django.utils.unittest import skipIf, skipUnless
 
 
 class BaseTaggingTest(object):
@@ -87,6 +88,14 @@ class TagModelTestCase(BaseTaggingTransactionTestCase):
             "category-awesome-1"
         ], attr="slug")
 
+    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, (
+                r"Cannot add 1 \(<(type|class) 'int'>\). "
+                r"Expected <class 'django.db.models.base.ModelBase'> or str.")):
+            apple.tags.add(1)
+
 class TagModelDirectTestCase(TagModelTestCase):
     food_model = DirectFood
     tag_model = Tag
@@ -109,7 +118,7 @@ class TaggableManagerTestCase(BaseTaggingTestCase):
     def test_add_tag(self):
         apple = self.food_model.objects.create(name="apple")
         self.assertEqual(list(apple.tags.all()), [])
-        self.assertEqual(list(self.food_model.tags.all()),  [])
+        self.assertEqual(list(self.food_model.tags.all()), [])
 
         apple.tags.add('green')
         self.assert_tags_equal(apple.tags.all(), ['green'])
@@ -150,7 +159,7 @@ class TaggableManagerTestCase(BaseTaggingTestCase):
         #      make sure we don't double create.
         # + 12 on Django 1.6 for save points.
         queries = 22
-        if django.VERSION < (1,6):
+        if django.VERSION < (1, 6):
             queries -= 12
         self.assertNumQueries(queries, apple.tags.add, "red", "delicious", "green")
 
@@ -160,7 +169,7 @@ class TaggableManagerTestCase(BaseTaggingTestCase):
         #     make sure we dont't double create.
         # + 4 on Django 1.6 for save points.
         queries = 9
-        if django.VERSION < (1,6):
+        if django.VERSION < (1, 6):
             queries -= 4
         self.assertNumQueries(queries, pear.tags.add, "green", "delicious")
 
@@ -181,7 +190,7 @@ class TaggableManagerTestCase(BaseTaggingTestCase):
 
     def test_delete_bulk(self):
         apple = self.food_model.objects.create(name="apple")
-        kitty = self.pet_model.objects.create(pk=apple.pk,  name="kitty")
+        kitty = self.pet_model.objects.create(pk=apple.pk, name="kitty")
 
         apple.tags.add("red", "delicious", "fruit")
         kitty.tags.add("feline")
@@ -222,9 +231,9 @@ class TaggableManagerTestCase(BaseTaggingTestCase):
         pks = self.pet_model.objects.filter(tags__name__in=["fuzzy"])
         model_name = self.pet_model.__name__
         self.assertQuerysetEqual(pks,
-            ['<{0}: kitty>'.format(model_name),
-             '<{0}: cat>'.format(model_name)],
-            ordered=False)
+                                 ['<{0}: kitty>'.format(model_name),
+                                  '<{0}: cat>'.format(model_name)],
+                                 ordered=False)
 
     def test_lookup_bulk(self):
         apple = self.food_model.objects.create(name="apple")
@@ -254,14 +263,14 @@ class TaggableManagerTestCase(BaseTaggingTestCase):
         pear = self.food_model.objects.create(name="pear")
         pear.tags.add("green", "delicious")
 
-        guava = self.food_model.objects.create(name="guava")
+        self.food_model.objects.create(name="guava")
 
         pks = self.food_model.objects.exclude(tags__name__in=["red"])
         model_name = self.food_model.__name__
         self.assertQuerysetEqual(pks,
-            ['<{0}: pear>'.format(model_name),
-             '<{0}: guava>'.format(model_name)],
-            ordered=False)
+                                 ['<{0}: pear>'.format(model_name),
+                                  '<{0}: guava>'.format(model_name)],
+                                 ordered=False)
 
     def test_similarity_by_tag(self):
         """Test that pears are more similar to apples than watermelons"""
@@ -293,8 +302,8 @@ class TaggableManagerTestCase(BaseTaggingTestCase):
             '%s__name' % _model_name(self.pet_model): 'Spot'
         }
         self.assert_tags_equal(
-           self.tag_model.objects.filter(**lookup_kwargs),
-           ['scary']
+            self.tag_model.objects.filter(**lookup_kwargs),
+            ['scary']
         )
 
     def test_taggeditem_unicode(self):
@@ -492,7 +501,7 @@ class TagStringParseTestCase(UnitTestCase):
         self.assertEqual(parse_tags(',one two'), ['one two'])
         self.assertEqual(parse_tags(',one two three'), ['one two three'])
         self.assertEqual(parse_tags('a-one, a-two and a-three'),
-            ['a-one', 'a-two and a-three'])
+                         ['a-one', 'a-two and a-three'])
 
     def test_with_double_quoted_multiple_words(self):
         """
@@ -504,7 +513,7 @@ class TagStringParseTestCase(UnitTestCase):
         self.assertEqual(parse_tags('"one two three'), ['one', 'three', 'two'])
         self.assertEqual(parse_tags('"one two"'), ['one two'])
         self.assertEqual(parse_tags('a-one "a-two and a-three"'),
-            ['a-one', 'a-two and a-three'])
+                         ['a-one', 'a-two and a-three'])
 
     def test_with_no_loose_commas(self):
         """
@@ -523,9 +532,9 @@ class TagStringParseTestCase(UnitTestCase):
         Double quotes can contain commas
         """
         self.assertEqual(parse_tags('a-one "a-two, and a-three"'),
-            ['a-one', 'a-two, and a-three'])
+                         ['a-one', 'a-two, and a-three'])
         self.assertEqual(parse_tags('"two", one, one, two, "one"'),
-            ['one', 'two'])
+                         ['one', 'two'])
 
     def test_with_naughty_input(self):
         """
@@ -540,7 +549,7 @@ class TagStringParseTestCase(UnitTestCase):
         self.assertEqual(parse_tags(',,,,,,'), [])
         self.assertEqual(parse_tags('",",",",",",","'), [','])
         self.assertEqual(parse_tags('a-one "a-two" and "a-three'),
-            ['a-one', 'a-three', 'a-two', 'and'])
+                         ['a-one', 'a-three', 'a-two', 'and'])
 
     def test_recreation_of_tag_list_string_representations(self):
         plain = Tag.objects.create(name='plain')
@@ -571,3 +580,20 @@ class SouthSupportTests(TestCase):
         except ImproperlyConfigured as e:
             exception = e
         self.assertIn("SOUTH_MIGRATION_MODULES", exception.args[0])
+
+
+class InheritedPrefetchTests(TestCase):
+
+    def test_inherited_tags_with_prefetch(self):
+        child = Child()
+        child.save()
+        child.tags.add('tag 1', 'tag 2', 'tag 3', 'tag 4')
+
+        child = Child.objects.get()
+        no_prefetch_tags = child.tags.all()
+        self.assertEquals(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]))
diff --git a/tox.ini b/tox.ini
index 84d7c57..7d0ef42 100644
--- a/tox.ini
+++ b/tox.ini
@@ -13,7 +13,7 @@ deps17 =
 	https://github.com/django/django/archive/stable/1.7.x.zip#egg=django
 
 commands =
-	python ./runtests.py
+	python ./runtests.py {posargs}
 
 
 [testenv:py26-1.4.x]

-- 
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