> I have a generic relation Flag, with a FlagType:
>
> class FlagType(models.Model):
>      name = models.CharField(maxlength=50)
>      description = models.TextField()
>
> class Flag(models.Model):
>      type = models.ForeignKey(FlagType) # type of flag
>      content_type = models.ForeignKey(ContentType)
>      object_id = models.PositiveIntegerField()
>      content_object = generic.GenericForeignKey()
>      user = models.ForeignKey(User)
>      created = models.DateTimeField()
>
> So, for example "illegal" or "to feature" would be flags. Now we're
> flagging Song objects and I would like a queryset that gets me all Songs
> flagged with a flag of type "illegal".
>
> I can do:
>
>    flag = FlagType.objects.get(name='illegal')
>    ctype = ContentType.objects.get_for_model(Song)
>    flagged = Flag.objects.filter(type=flag,
>                content_type=ctype).order_by('-created')
>    songs = [item.content_object for item in flagged ]
>
> But the problem is: I can't do extra things to this list like order_by()
> or an extra filter() or exclude().
>
> How can I get the same result, but still have a queryset (containing
> Songs) instead of a list??

This looks similar to what the TaggedItemManager needs to do in
django-tagging [1] - here's a completely untested, adapted version of
its get_by_model method - does this work for you?

models.py::

from django.contrib.contenttypes.models import ContentType
from django.db import backend, models

class FlagManager(models.Manager):
    def get_by_model_and_flag_type(self, Model, type_name):
        """
        Create a ``QuerySet`` containing instances of the given model
        class associated with a ``FlagType`` with the given name.
        """
        flag_type = FlagType.objects.get(name=type_name)
        ctype = ContentType.objects.get_for_model(Model)
        rel_table = backend.quote_name(self.model._meta.db_table)
        return Model._default_manager.extra(
            tables=[self.model._meta.db_table], # Use a non-explicit join
            where=[
                '%s.content_type_id = %%s' % rel_table,
                '%s.type_id = %%s' % rel_table,
                '%s.%s = %s.object_id' %
(backend.quote_name(Model._meta.db_table),

backend.quote_name(Model._meta.pk.column),
                                          rel_table)
            ],
            params=[ctype.id, flag_type.id],
        )

class Flag(models.Model):
    ...

    objects = FlagManager()


Usage::

songs = Flag.objects.get_by_model_and_flag_type(Song, 'illegal')

Regards,
Jonathan.

[1] http://code.google.com/p/django-tagging/

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Django users" group.
To post to this group, send email to django-users@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-users?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to