2

我有一个名为“Comments”的模型,它使用通用外键:

class CommentManager(models.Manager):

    def for_model(self, model):
        """
        QuerySet for all comments for a particular model (either an instance or
        a class).
        """
        ct = ContentType.objects.get_for_model(model)
        qs = self.get_query_set().filter(content_type=ct)
        if isinstance(model, models.Model):
            qs = qs.filter(object_pk=force_text(model._get_pk_val()))
        return qs


class Comment(models.Model):
    """
    A user comment about some object.
    """
    status = models.CharField(max_length=12, blank=True, null=True)
    sub_status = models.CharField(max_length=500, blank=True, null=True)
    comment = models.TextField()

    content_type = models.ForeignKey(
        ContentType,
        verbose_name=_('content type'),
        related_name="content_type_set_for_%(class)s")
    object_pk = models.TextField(_('object ID'))
    content_object = generic.GenericForeignKey(ct_field="content_type",
                                               fk_field="object_pk")

您可以发表评论的其中一件事是Tickets

class Ticket(CommonModel):
    type = models.ForeignKey(TicketType)
    priority = models.PositiveSmallIntegerField()
    status = models.ForeignKey(TicketStatus)
    access_serial_number = models.PositiveSmallIntegerField(null=True)
    parent = models.ForeignKey('self', null=True, related_name='child')
    submitted = models.DateTimeField()

我做了很多过滤Tickets- 过去我对门票的评论所做的只是当我显示 a 时Ticket,我曾经Comments.objects.for_model(ticket)找到它的所有评论。但现在我想做的是Tickets在评论中找到特定的文本。没有comment_set或等价于GenericForeignKey

这是我想出的,但它非常可怕:

comment_ticket_ids = [int(c.object_pk) for c in Comment.objects.for_model(Ticket).filter(comment__icontains='error')]
tickets = Ticket.filter(status=open_status, id__in=comment_ticket_ids)

一定会有更好的办法。

4

1 回答 1

0

也许你可以添加一些东西.extra()来帮助。代替

comment_ticket_ids = [int(c.object_pk) for c in Comment.objects.for_model(Ticket).filter(comment__icontains='error')]
tickets = Ticket.filter(status=open_status, id__in=comment_ticket_ids)

您可以附加该字段id_wanted

extra_select = {
 'id_wanted': 'CASE WHEN (SELECT COUNT(*) FROM tickets WHERE comments something) > 0 THEN TRUE ELSE FALSE END'
}

然后使用额外选择过滤票证:

tickets = Tickets.objects.filter(ticket__status=open_status, id_wanted__isnull=False).extra(extra_select)

我不完全清楚为什么你不能在这两个模型之间建立 FKey 关系。

于 2015-09-17T21:49:55.283 回答