Skip to content

Instantly share code, notes, and snippets.

@pokidovea
Created March 28, 2013 09:58
Show Gist options
  • Save pokidovea/5262080 to your computer and use it in GitHub Desktop.
Save pokidovea/5262080 to your computer and use it in GitHub Desktop.
Django form field on the basis of jQuery plugin Tag-It! http://aehlke.github.com/tag-it/
class TagitWidget(forms.HiddenInput):
""" Widget on the basis of Tag-It! http://aehlke.github.com/tag-it/"""
class Media:
js = (settings.STATIC_URL + 'js/tag-it.js',
settings.STATIC_URL + 'js/tagit_widget.js',)
css = {"all": (settings.STATIC_URL + 'css/jquery.tagit.css',)}
class TagitField(forms.Field):
""" Tag field """
widget = TagitWidget
def __init__(self, tag_model, *args, **kwargs):
self.tag_model = tag_model
super(TagitField, self).__init__(*args, **kwargs)
def to_python(self, value):
tag_strings = value.split(',')
return [self.tag_model.get_or_create(tag_string) for tag_string in tag_strings if len(tag_string) > 0]
def validate(self, value):
if len(value) == 0 and self.required:
raise ValidationError(self.error_messages['required'])
def prepare_value(self, value):
if value is not None and hasattr(value, '__iter__'):
return ','.join((unicode(tag) for tag in value))
return value
def widget_attrs(self, widget):
res = super(TagitField, self).widget_attrs(widget) or {}
res["class"] = "tagit"
return res
class Tag(models.Model):
""" Model of Tags """
name = models.CharField(max_length=200, null=False, verbose_name="Tag name")
slug = models.CharField(max_length=400,
editable=False,
verbose_name=u'Slug',
unique=True,
null=False)
def __unicode__(self):
return self.name
@staticmethod
def _generate_slug(value):
slug = ''.join(ch for ch in value[:200] if category(ch)[0] != 'P')
return urlquote(re.sub(r'([ ]+_)|(_[ ]+)|([ ]+)', '_', slug))
def save(self, *args, **kwargs):
self.name = self.name.lower()
self.slug = self._generate_slug(self.name)
super(Tag, self).save(*args, **kwargs)
@classmethod
def get_or_create(cls, value):
slug = cls._generate_slug(value.lower().strip())
if cls.objects.filter(slug=slug).exists():
return cls.objects.get(slug=slug)
else:
return cls.objects.create(name=value.lower().strip())
$(document).ready(function() {
$(".tagit").tagit({
allowSpaces: true,
autocomplete: {
delay: 0,
minLength: 2,
source: "/tag_autocomplete/"
}
});
});
@login_required
def tag_autocomplete(request):
""" url: /tag_autocomplete/"""
if not request.is_ajax():
raise Http404
value = request.GET['term']
available_tags = Tag.objects.filter(name__startswith=value.lower())
response = HttpResponse(json.dumps([unicode(tag) for tag in available_tags]))
return response
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment