2

I've been trying to implement a tagging system for my application, where only certain tags are allowed for each content type.

I've tried setting the content type on the Tag model, and using this value on the TagAttribution model, and have got... interesting results.

Code:

from django.db import models
from django.contrib.contenttypes.models import ContentType
from django.contrib.contenttypes import generic
from django.contrib.auth.models import User

class Tag(models.Model):
    value = models.CharField(max_length=32)
    created_by = models.ForeignKey(User)
    appliable_to = models.ForeignKey(ContentType)

    def __unicode__(self):
        return self.value

class TagAttribution(models.Model):
    tag = models.ForeignKey(Tag)
    object_id = models.PositiveIntegerField()
    content_object = generic.GenericForeignKey('tag__appliable_to', 'object_id')

    def __unicode__(self):
        return "%s for id %s of class %s" % (self.tag.value, self.object_id, self.content_object.model) 

Shell test:

ct = ContentType.objects.get(model='company')
tag = Tag()
tag.value = 'value'
tag.created_by = User.objects.get(id=1)
tag.appliable_to = ct
tag.save()
ta = TagAttribution()
ta.tag = tag
ta.object_id = Company.objects.get(id=1).id
ta.content_object = ta.tag.appliable_to
ta.save()
ta

Output:

<TagAttribution: value for id 13 of class company>

I don't understand this behavior; why has it got the id 13 if I had used company id 1?

Kristian Glass
  • 37,325
  • 7
  • 45
  • 73
Wilerson
  • 347
  • 1
  • 5
  • 14

1 Answers1

3

Error is here:

ta.content_object = ta.tag.appliable_to

The ta.content_object here is not Company object but ContentType. Correct code should be:

ta.content_object = Company.objects.get(id=1).id

Also, you don't have to set ta.object_id directly, it's done by GenericForeignKey field

ilvar
  • 5,718
  • 1
  • 20
  • 17
  • Sadly, that doesn't seem to work. Your code renders `AttributeError: 'int' object has no attribute '_state'` . I removed the last `id` , and the error was `AttributeError: 'Company' object has no attribute 'model'` – Wilerson Mar 02 '12 at 13:41
  • Eventually, I figured out that, apart from the `id`, your solution is correct, and my code was breaking on the `__unicode__` method in `TagAttribution`. – Wilerson Mar 02 '12 at 19:20