Search code examples
djangom2mgeneric-foreign-key

Django: Returning objects when using a generic relationship as a through model


I have the following setup that i want to use to tag generic objects (at the moment just the one type, a resource object).

class Resource(models.Model):
    ...
    tag_items = GenericRelation(TaggedItem, related_query_name='resources')

    @property
    def platform(self):
        return self.tag_items.filter(relationship=TaggedItem.PLATFORM)

    @property
    def characteristics(self):
        return self.tag_items.filter(relationship=TaggedItem.CHARACTERISTICS)


class Tag(models.Model):
    ...


class TaggedItem(models.Model):
    # Relationship choices
    PLATFORM = 'platform'
    CHARACTERISTICS = 'characteristics'
    RELATIONSHIP_CHOICES = (
        (PLATFORM, 'Platform'),
        (CHARACTERISTICS, 'Characteristics'))

    tag = models.ForeignKey(Tag, related_name="%(class)s_items")
    content_type = models.ForeignKey(ContentType, related_name="%(class)s_tagged_items")
    object_id = models.PositiveIntegerField(db_index=True)
    object = GenericForeignKey('content_type', 'object_id')
    relationship = models.CharField(choices=RELATIONSHIP_CHOICES, default=CHARACTERISTICS, max_length=50)

What i want is for resource.platform/characteristics to return a list of tag objects rather than the through model TaggedItem objects.

Can't quite figure out the best way to do it though. Any thoughts? Is this even a sensible approach?


Solution

  • Try this one:

    class Resource(models.Model):
        #...
        tag_items = GenericRelation(TaggedItem, related_query_name='resources')
    
        @property
        def platform(self):
            return Tag.objects.filter(
                taggetitem_items__resources=self,
                taggetitem_items__relationship=TaggedItem.PLATFORM,
            )
    
        @property
        def characteristics(self):
            return Tag.objects.filter(
                taggetitem_items__resources=self,
                taggetitem_items__relationship=TaggedItem.CHARACTERISTICS,
            )