Skip to content

Commit

Permalink
Merge branch 'develop'
Browse files Browse the repository at this point in the history
  • Loading branch information
apollo13 committed Sep 21, 2014
2 parents 316ee15 + 20780f9 commit ed8af52
Show file tree
Hide file tree
Showing 15 changed files with 199 additions and 107 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.txt
Original file line number Diff line number Diff line change
@@ -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.
Expand Down
11 changes: 11 additions & 0 deletions setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,14 @@ license-file = LICENSE

[wheel]
universal=1

[flake8]
# ignore=NONE
# max-line-length=100

# E302: expected 2 blank lines, found 1 [E302]
# E501: line too long
ignore=E501,E302

[isort]
forced_separate=tests,taggit
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

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',
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, 1)
VERSION = (0, 12, 2)
11 changes: 7 additions & 4 deletions taggit/forms.py
Original file line number Diff line number Diff line change
@@ -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

Expand All @@ -21,4 +23,5 @@ def clean(self, value):
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."))
77 changes: 46 additions & 31 deletions taggit/managers.py
Original file line number Diff line number Diff line change
@@ -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):
Expand Down Expand Up @@ -102,21 +106,21 @@ def get_prefetch_queryset(self, instances, queryset=None):
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
source_col = fk.column
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)

Expand All @@ -129,12 +133,17 @@ def _lookup_kwargs(self):

@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(
Expand Down Expand Up @@ -220,10 +229,12 @@ def similar_objects(self):
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
Expand All @@ -233,12 +244,12 @@ def __init__(self, verbose_name=_("Tags"), help_text=_("A comma-separated list o
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

Expand Down Expand Up @@ -287,7 +298,6 @@ def resolve_related_class(field, model, cls):
else:
self.post_through_setup(cls)


def __lt__(self, other):
"""
Required contribute_to_class as Django uses bisect
Expand Down Expand Up @@ -364,7 +374,7 @@ def bulk_related_objects(self, new_objs, using):
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:
Expand All @@ -378,13 +388,18 @@ def get_extra_join_sql(self, connection, qn, lhs_alias, rhs_alias):
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

Expand Down Expand Up @@ -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

Expand Down
7 changes: 4 additions & 3 deletions taggit/migrations/0001_initial.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# encoding: utf8
# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.db import models, migrations


Expand Down Expand Up @@ -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',
Expand Down
16 changes: 9 additions & 7 deletions taggit/models.py
Original file line number Diff line number Diff line change
@@ -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:
Expand Down Expand Up @@ -59,7 +61,7 @@ def save(self, *args, **kwargs):
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:
Expand Down Expand Up @@ -145,7 +147,7 @@ class GenericTaggedItemBase(ItemBase):
content_object = GenericForeignKey()

class Meta:
abstract=True
abstract = True

@classmethod
def lookup_kwargs(cls, instance):
Expand Down
2 changes: 1 addition & 1 deletion taggit/utils.py
Original file line number Diff line number Diff line change
@@ -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):
Expand Down
3 changes: 1 addition & 2 deletions taggit/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
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):
Expand All @@ -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)

7 changes: 3 additions & 4 deletions tests/forms.py
Original file line number Diff line number Diff line change
@@ -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__'


Expand Down

0 comments on commit ed8af52

Please sign in to comment.