Custom Chainable QuerySet - PullRequest
       26

Custom Chainable QuerySet

0 голосов
/ 16 апреля 2011

Это часть моего кода

from django.db import models
from django.db.models.query import QuerySet
from mptt.models import MPTTModel
from base.models import Content, OrderedContent


class ArgumentQuerySet(QuerySet):
    def statements_with_count(self, *args, **kwargs):
        from statement.models import Statement
        statements = Statement.objects.none()
        result = self
        for node in result:
            statements_node = Statement.objects.filter( arguments__in = node.get_descendants(include_self = True), *args, **kwargs ).distinct()
            statements |= statements_node
            setattr(node, 'count', statements_node.count())
        statements = statements.distinct()
        setattr(result, 'statements', statements)
        setattr(result, 'count', statements.count())
        return result


class ArgumentManager(models.Manager):
    def get_query_set(self):
        return ArgumentQuerySet(self.model)


class Argument(MPTTModel, OrderedContent):
    parent = models.ForeignKey('self', null=True, blank=True)
    objects = ArgumentManager()

    class MPTTMeta:
        parent_attr = 'parent'
        order_insertion_by = ['weight', 'title', ]

    def __unicode__(self):
        return self.title

Следующие команды дают мне результат

a = Argument.objects.filter( title__icontains = 'function' )
b = a.statements_with_count()

В противном случае следующие команды не работают

c = Argument.objects.get( id = 514 )
d = c.get_children()
e = d.statements_with_count()

Как я могу решить эту проблему?

1 Ответ

0 голосов
/ 16 апреля 2011

MPTT использует TreeManager экземпляр для get_children, который возвращает models.query.Queryset, а не ваш пользовательский подкласс. Вы должны сделать что-то вроде:

argument = Argument.objects.get(id = 514)
children_ids = [a.pk for a in argument.get_children()]
result = Argument.objects.filter(pk__in=children_ids).statements_with_count()

Обратите внимание, что ваш метод statements_with_count не очень эффективен, так как он вызовет один дополнительный счетчик базы данных для каждого объекта.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...