From d03c8d2d2efaf848b01e96863c29f46ce3a0db21 Mon Sep 17 00:00:00 2001 From: SVN-Git Migration Date: Thu, 8 Oct 2015 11:51:46 -0700 Subject: Imported Upstream version 0.2.1+svn147 --- tagging/fields.py | 219 +++++++++++++++++++++++++++--------------------------- 1 file changed, 109 insertions(+), 110 deletions(-) (limited to 'tagging/fields.py') diff --git a/tagging/fields.py b/tagging/fields.py index c9475f6..5b39e84 100644 --- a/tagging/fields.py +++ b/tagging/fields.py @@ -1,110 +1,109 @@ -""" -A custom Model Field for tagging. -""" -from django.db.models import signals -from django.db.models.fields import CharField -from django.dispatch import dispatcher -from django.utils.translation import ugettext_lazy as _ - -from tagging import settings -from tagging.models import Tag -from tagging.utils import edit_string_for_tags -from tagging.validators import isTagList - -class TagField(CharField): - """ - A "special" character field that actually works as a relationship to tags - "under the hood". This exposes a space-separated string of tags, but does - the splitting/reordering/etc. under the hood. - """ - def __init__(self, **kwargs): - kwargs['max_length'] = kwargs.get('max_length', 255) - kwargs['blank'] = kwargs.get('blank', True) - kwargs['validator_list'] = [isTagList] + kwargs.get('validator_list', []) - super(TagField, self).__init__(**kwargs) - - def contribute_to_class(self, cls, name): - super(TagField, self).contribute_to_class(cls, name) - - # Make this object the descriptor for field access. - setattr(cls, self.name, self) - - # Save tags back to the database post-save - dispatcher.connect(self._save, signal=signals.post_save, sender=cls) - - def __get__(self, instance, owner=None): - """ - Tag getter. Returns an instance's tags if accessed on an instance, and - all of a model's tags if called on a class. That is, this model:: - - class Link(models.Model): - ... - tags = TagField() - - Lets you do both of these:: - - >>> l = Link.objects.get(...) - >>> l.tags - 'tag1 tag2 tag3' - - >>> Link.tags - 'tag1 tag2 tag3 tag4' - - """ - # Handle access on the model (i.e. Link.tags) - if instance is None: - return edit_string_for_tags(Tag.objects.usage_for_model(owner)) - - tags = self._get_instance_tag_cache(instance) - if tags is None: - if instance.pk is None: - self._set_instance_tag_cache(instance, '') - else: - self._set_instance_tag_cache( - instance, edit_string_for_tags(Tag.objects.get_for_object(instance))) - return self._get_instance_tag_cache(instance) - - def __set__(self, instance, value): - """ - Set an object's tags. - """ - if instance is None: - raise AttributeError(_('%s can only be set on instances.') % self.name) - if settings.FORCE_LOWERCASE_TAGS and value is not None: - value = value.lower() - self._set_instance_tag_cache(instance, value) - - def _save(self, signal, sender, instance): - """ - Save tags back to the database - """ - tags = self._get_instance_tag_cache(instance) - if tags is not None: - Tag.objects.update_tags(instance, tags) - - def __delete__(self, instance): - """ - Clear all of an object's tags. - """ - self._set_instance_tag_cache(instance, '') - - def _get_instance_tag_cache(self, instance): - """ - Helper: get an instance's tag cache. - """ - return getattr(instance, '_%s_cache' % self.attname, None) - - def _set_instance_tag_cache(self, instance, tags): - """ - Helper: set an instance's tag cache. - """ - setattr(instance, '_%s_cache' % self.attname, tags) - - def get_internal_type(self): - return 'CharField' - - def formfield(self, **kwargs): - from tagging import forms - defaults = {'form_class': forms.TagField} - defaults.update(kwargs) - return super(TagField, self).formfield(**defaults) +""" +A custom Model Field for tagging. +""" +from django.db.models import signals +from django.db.models.fields import CharField +from django.utils.translation import ugettext_lazy as _ + +from tagging import settings +from tagging.models import Tag +from tagging.utils import edit_string_for_tags +from tagging.validators import isTagList + +class TagField(CharField): + """ + A "special" character field that actually works as a relationship to tags + "under the hood". This exposes a space-separated string of tags, but does + the splitting/reordering/etc. under the hood. + """ + def __init__(self, *args, **kwargs): + kwargs['max_length'] = kwargs.get('max_length', 255) + kwargs['blank'] = kwargs.get('blank', True) + kwargs['validator_list'] = [isTagList] + kwargs.get('validator_list', []) + super(TagField, self).__init__(*args, **kwargs) + + def contribute_to_class(self, cls, name): + super(TagField, self).contribute_to_class(cls, name) + + # Make this object the descriptor for field access. + setattr(cls, self.name, self) + + # Save tags back to the database post-save + signals.post_save.connect(self._save, cls, True) + + def __get__(self, instance, owner=None): + """ + Tag getter. Returns an instance's tags if accessed on an instance, and + all of a model's tags if called on a class. That is, this model:: + + class Link(models.Model): + ... + tags = TagField() + + Lets you do both of these:: + + >>> l = Link.objects.get(...) + >>> l.tags + 'tag1 tag2 tag3' + + >>> Link.tags + 'tag1 tag2 tag3 tag4' + + """ + # Handle access on the model (i.e. Link.tags) + if instance is None: + return edit_string_for_tags(Tag.objects.usage_for_model(owner)) + + tags = self._get_instance_tag_cache(instance) + if tags is None: + if instance.pk is None: + self._set_instance_tag_cache(instance, '') + else: + self._set_instance_tag_cache( + instance, edit_string_for_tags(Tag.objects.get_for_object(instance))) + return self._get_instance_tag_cache(instance) + + def __set__(self, instance, value): + """ + Set an object's tags. + """ + if instance is None: + raise AttributeError(_('%s can only be set on instances.') % self.name) + if settings.FORCE_LOWERCASE_TAGS and value is not None: + value = value.lower() + self._set_instance_tag_cache(instance, value) + + def _save(self, **kwargs): #signal, sender, instance): + """ + Save tags back to the database + """ + tags = self._get_instance_tag_cache(kwargs['instance']) + if tags is not None: + Tag.objects.update_tags(kwargs['instance'], tags) + + def __delete__(self, instance): + """ + Clear all of an object's tags. + """ + self._set_instance_tag_cache(instance, '') + + def _get_instance_tag_cache(self, instance): + """ + Helper: get an instance's tag cache. + """ + return getattr(instance, '_%s_cache' % self.attname, None) + + def _set_instance_tag_cache(self, instance, tags): + """ + Helper: set an instance's tag cache. + """ + setattr(instance, '_%s_cache' % self.attname, tags) + + def get_internal_type(self): + return 'CharField' + + def formfield(self, **kwargs): + from tagging import forms + defaults = {'form_class': forms.TagField} + defaults.update(kwargs) + return super(TagField, self).formfield(**defaults) -- cgit v1.2.3