Login

TaggedManager and TaggedQuerySet with chainable tagged() methods implemented with django-tagging

Author:
fish2000
Posted:
February 25, 2010
Language:
Python
Version:
1.1
Tags:
manager queryset django-tagging django1.1 chainable
Score:
1 (after 1 ratings)

The popular django-tagging app has, in its implementation and semantics, a highly usable and transparent elegance -- but then you have to call methods on a Tag instances' items collection. These classes let you inline the tag name in the chain of queryset filter methods instead.

TO USE:

### models.py
...
from tagging.fields import TagField
from tagging.models import Tag as Tag

class YourModel(models.Model):
    ...
    yourtags = TagField()
    objects = TaggedManager()
    ...

### and then elsewhere, something like--
...
ym = YourModel.objects.order_by("-modifydate")[0]
anotherym = YourModel.objects.get(id=7) ## distinct from ym

ym.yourtags = "tag1 tag2"
anotherym.yourtags = "tag1 othertag"

ym.save()
anotherym.save()

with_tag1 = YourModel.objects.tagged('tag1')
with_tag2 = YourModel.objects.tagged('tag2').order_by('-modifydate')

print ym in with_tag1            ## True
print anotherym in with_tag1     ## True
print ym in with_tag2            ## False

... since these are QuerySets, you can easily create unions (e.g. with_tag1 | with_tag2 and othersuch) as you need and filter them to your hearts' content, without having to instantiate Tag all the time (which you can of course do as well).

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
from django.db import models
from django.core.exceptions import ObjectDoesNotExist
from tagging.models import Tag

class TaggedQuerySet(models.query.QuerySet):
	def tagged(self, name=None):
		if name:
			try:
				t = Tag.objects.filter(name=name).get()
			except ObjectDoesNotExist:
				return self.none()
			else:
				return self.filter(
					pk__in=t.items.get_by_model(self.model, t).values('pk').query
				)
		return self.none()


class TaggedManager(models.Manager):
	def __init__(self, fields=None, *args, **kwargs):
		super(TaggedManager, self).__init__(*args, **kwargs)
		self._fields = fields
	def get_query_set(self):
		return TaggedQuerySet(self.model, self._fields)
	def tagged(self, name=None):
		return self.get_query_set().tagged(name)

More like this

  1. Easier chainability with custom QuerySets by bendavis78 3 years, 2 months ago
  2. Custom managers with chainable filters by itavor 7 years, 4 months ago
  3. common model privacy by teepark 7 years, 9 months ago
  4. Django Dictionary Model by Morgul 3 years, 11 months ago
  5. Filter on Multiple M2M Objects Simultaneously by axiak 8 years, 1 month ago

Comments

fish2000 (on February 25, 2010):

EDIT: changed 'id' to 'pk' in tagged() to keep it from choking on non-default keys.

#

Please login first before commenting.