Менеджер моделей Django не работал со связанным объектом, когда я выполнял агрегированный запрос - PullRequest
1 голос
/ 14 апреля 2010

У меня проблемы с выполнением запроса агрегации в связанном поле многие ко многим.

Вот мои модели:

class SortedTagManager(models.Manager):
    use_for_related_fields = True

    def get_query_set(self):
        orig_query_set = super(SortedTagManager, self).get_query_set()
        # FIXME `used` is wrongly counted
        return orig_query_set.distinct().annotate(
                    used=models.Count('users')).order_by('-used')


class Tag(models.Model):
    content = models.CharField(max_length=32, unique=True)
    creator = models.ForeignKey(User, related_name='tags_i_created')
    users = models.ManyToManyField(User, through='TaggedNote',
                                   related_name='tags_i_used')

    objects_sorted_by_used = SortedTagManager()

class TaggedNote(models.Model):
    """Association table of both (Tag , Note) and (Tag, User)"""
    note = models.ForeignKey(Note) # Note is what's tagged in my app
    tag = models.ForeignKey(Tag)
    tagged_by = models.ForeignKey(User)

    class Meta:
        unique_together = (('note', 'tag'),)

Однако значение агрегированного поля used является правильным, только если модель запрашивается напрямую:

for t in Tag.objects.all(): print t.used # this works correctly

for t in user.tags_i_used.all(): print t.used #prints n^2 when it should give n

Не могли бы вы сказать мне, что с ним не так? Заранее спасибо.

1 Ответ

2 голосов
/ 14 апреля 2010

Я разобрался, что не так и как это исправить сейчас:)

  1. Как указано в документе Django:

Django интерпретирует первый Manager, определенный в классе, как «менеджер по умолчанию», и несколько частей Django будут использовать этот Manager исключительно для этой модели.

В моем случае я должен убедиться, что SortedTagManager является первым Manager определенным.

2.У меня должен быть счет notes вместо users:

Count('notes', distinct=True)
...