【问题标题】:Django generic foreign key reverse filterDjango通用外键反向过滤器
【发布时间】:2015-09-17 18:12:36
【问题描述】:

我有一个名为“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")

你可以放 cmets 的东西之一是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()

我对@9​​87654324@ 做了很多过滤——过去我对门票的评论所做的只是当我显示Ticket 时,我使用Comments.objects.for_model(ticket) 来查找它的所有评论。但现在我想做的是找到Tickets 在评论中有特定文本。没有comment_setGenericForeignKey 的等价物。

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

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)

一定有更好的办法。

【问题讨论】:

  • 您如何将CommentsTickets 关联起来?我已多次阅读您的问题,但在您的代码示例中看不到这种关系。
  • 我使用GenericForeignKey content_object 将cmets 添加到票证中,如comment = Comment(content_object=my_ticket, status="Ticket Created", comment="So and so created this ticket for grins").save()

标签: django generic-foreign-key


【解决方案1】:

也许您可以使用.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 关系。

【讨论】:

  • 1.我们使用 GenericForeignKey 是因为您可以将评论附加到门票以外的东西上。
  • 2.我不清楚您的建议是如何工作的 - 它似乎将 id_wanted 附加到评论,然后期望它出现在不涉及评论的查询中?
  • 我修改了我的答案 - 如果没有用,将删除。我正在尝试翻译我使用的模式,其中我也有一个内容类型关系(允许在许多不同的对象上使用 cmets)并在我们的查询集中使用了 .extra() 子句
猜你喜欢
  • 1970-01-01
  • 2021-07-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-24
  • 1970-01-01
  • 2016-12-09
  • 2021-07-27
相关资源
最近更新 更多