Skip to content

Commit

Permalink
Merge branch 'develop'
Browse files Browse the repository at this point in the history
  • Loading branch information
frewsxcv committed Apr 3, 2015
2 parents d8ac0d9 + 54840c8 commit 24df08c
Show file tree
Hide file tree
Showing 8 changed files with 106 additions and 22 deletions.
3 changes: 3 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,15 @@ env:
- TOXENV=py27-1.5.x
- TOXENV=py27-1.6.x
- TOXENV=py27-1.7.x
- TOXENV=py27-1.8.x
- TOXENV=py33-1.5.x
- TOXENV=py33-1.6.x
- TOXENV=py33-1.7.x
- TOXENV=py33-1.8.x
- TOXENV=py34-1.5.x
- TOXENV=py34-1.6.x
- TOXENV=py34-1.7.x
- TOXENV=py34-1.8.x
install:
- pip install flake8 tox
before_script:
Expand Down
5 changes: 5 additions & 0 deletions CHANGELOG.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
Changelog
=========

0.13.0 (04.02.2015)
~~~~~~~~~~~~~~~~~~~
* Django 1.8 support
* https://github.com/alex/django-taggit/pull/297

0.12.3 (03.03.2015)
~~~~~~~~~~~~~~~~~~~
* Specify that the internal type of the TaggitManager is a ManyToManyField
Expand Down
2 changes: 1 addition & 1 deletion README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,6 @@ Tags will show up for you automatically in forms and the admin.

``django-taggit`` requires Django 1.4.5 or greater.

For more info check out the documentation. And for questions about usage or
For more info check out the `documentation <https://django-taggit.readthedocs.org/en/latest/>`_. And for questions about usage or
development you can contact the
`mailinglist <http://groups.google.com/group/django-taggit>`_.
9 changes: 5 additions & 4 deletions setup.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
from setuptools import setup, find_packages

import taggit

f = open('README.rst')
readme = f.read()
f.close()

with open('README.rst') as f:
readme = f.read()

setup(
name='django-taggit',
version='0.12.3',
version='.'.join(str(i) for i in taggit.VERSION),
description='django-taggit is a reusable Django application for simple tagging.',
long_description=readme,
author='Alex Gaynor',
Expand Down
2 changes: 1 addition & 1 deletion taggit/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
VERSION = (0, 12, 2)
VERSION = (0, 13, 0)
70 changes: 59 additions & 11 deletions taggit/managers.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,19 @@
from django.db import models, router
from django.db.models.fields import Field
from django.db.models.fields.related import (add_lazy_relation, ManyToManyRel,
RelatedField)
from django.db.models.related import RelatedObject
OneToOneRel, RelatedField)

if VERSION < (1, 8):
# related.py was removed in Django 1.8

# Depending on how Django was updated, related.py could still exist
# on the users system even on Django 1.8+, so we check the Django
# version before importing it to make sure this doesn't get imported
# accidentally.
from django.db.models.related import RelatedObject
else:
RelatedObject = None

from django.utils import six
from django.utils.text import capfirst
from django.utils.translation import ugettext_lazy as _
Expand All @@ -23,9 +34,12 @@
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 django.db.models.query_utils import PathInfo
except ImportError: # Django < 1.8
try:
from django.db.models.related import PathInfo
except ImportError:
pass # PathInfo is not used on Django < 1.6


def _model_name(model):
Expand Down Expand Up @@ -224,20 +238,42 @@ def similar_objects(self):
results.append(obj)
return results

# _TaggableManager needs to be hashable but BaseManagers in Django 1.8+ overrides
# the __eq__ method which makes the default __hash__ method disappear.
# This checks if the __hash__ attribute is None, and if so, it reinstates the original method.
if models.Manager.__hash__ is None:
__hash__ = object.__hash__


class TaggableManager(RelatedField, Field):
# Field flags
many_to_many = True
many_to_one = False
one_to_many = False
one_to_one = False

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

self.through = through or TaggedItem
self.rel = TaggableRel(self, related_name, self.through, to=to)
self.swappable = False
self.manager = manager

rel = TaggableRel(self, related_name, self.through, to=to)

Field.__init__(
self,
verbose_name=verbose_name,
help_text=help_text,
blank=blank,
null=True,
serialize=False,
rel=rel,
)
# NOTE: `to` is ignored, only used via `deconstruct`.

def __get__(self, instance, model):
Expand Down Expand Up @@ -309,13 +345,18 @@ def __lt__(self, other):
return False

def post_through_setup(self, cls):
self.related = RelatedObject(cls, self.model, self)
if RelatedObject is not None: # Django < 1.8
self.related = RelatedObject(cls, self.model, self)

self.use_gfk = (
self.through is None or issubclass(self.through, GenericTaggedItemBase)
)
if not self.rel.to:
self.rel.to = self.through._meta.get_field("tag").rel.to
self.related = RelatedObject(self.through, cls, self)

if RelatedObject is not None: # Django < 1.8
self.related = RelatedObject(self.through, cls, self)

if self.use_gfk:
tagged_items = GenericRelation(self.through)
tagged_items.contribute_to_class(cls, 'tagged_items')
Expand Down Expand Up @@ -477,7 +518,14 @@ def _get_subclasses(model):
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

# Django 1.8 +
if (not RelatedObject and isinstance(field, OneToOneRel) and
getattr(field.field.rel, "parent_link", None)):
subclasses.extend(_get_subclasses(field.related_model))

# < Django 1.8
if (RelatedObject and isinstance(field, RelatedObject) and
getattr(field.field.rel, "parent_link", None)):
subclasses.extend(_get_subclasses(field.model))
return subclasses
Expand Down
9 changes: 8 additions & 1 deletion tests/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -336,7 +336,14 @@ def test_field_api(self):
self.assertTrue(hasattr(field, 'rel'))
self.assertTrue(hasattr(field.rel, 'to'))
self.assertTrue(hasattr(field, 'related'))
self.assertEqual(self.food_model, field.related.model)

# This API has changed in Django 1.8
# https://code.djangoproject.com/ticket/21414
if django.VERSION >= (1, 8):
self.assertEqual(self.food_model, field.model)
self.assertEqual(self.tag_model, field.related.model)
else:
self.assertEqual(self.food_model, field.related.model)

def test_names_method(self):
apple = self.food_model.objects.create(name="apple")
Expand Down
28 changes: 24 additions & 4 deletions tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,15 @@ usedevelop = True
deps =
flake8
deps14 =
https://github.com/django/django/archive/stable/1.4.x.zip#egg=django
https://github.com/django/django/archive/stable/1.4.x.tar.gz#egg=django
deps15 =
https://github.com/django/django/archive/stable/1.5.x.zip#egg=django
https://github.com/django/django/archive/stable/1.5.x.tar.gz#egg=django
deps16 =
https://github.com/django/django/archive/stable/1.6.x.zip#egg=django
https://github.com/django/django/archive/stable/1.6.x.tar.gz#egg=django
deps17 =
https://github.com/django/django/archive/stable/1.7.x.zip#egg=django
https://github.com/django/django/archive/stable/1.7.x.tar.gz#egg=django
deps18 =
https://github.com/django/django/archive/stable/1.8.x.tar.gz#egg=django

commands =
python ./runtests.py {posargs}
Expand Down Expand Up @@ -58,6 +60,12 @@ deps =
{[testenv]deps}
{[testenv]deps17}

[testenv:py27-1.8.x]
basepython = python2.7
deps =
{[testenv]deps}
{[testenv]deps18}

[testenv:py33-1.5.x]
basepython = python3.3
deps =
Expand All @@ -76,6 +84,12 @@ deps =
{[testenv]deps}
{[testenv]deps17}

[testenv:py33-1.8.x]
basepython = python3.3
deps =
{[testenv]deps}
{[testenv]deps18}

[testenv:py34-1.5.x]
basepython = python3.4
deps =
Expand All @@ -93,3 +107,9 @@ basepython = python3.4
deps =
{[testenv]deps}
{[testenv]deps17}

[testenv:py34-1.8.x]
basepython = python3.4
deps =
{[testenv]deps}
{[testenv]deps18}

0 comments on commit 24df08c

Please sign in to comment.