django:如何根据 GenericForeignKey 的字段进行查询?



我是使用GenericForeignKey的新手,我无法在查询语句中使用它。这些表大致如下所示:

class Ticket(models.Model):
    issue_ct = models.ForeignKey(ContentType, related_name='issue_content_type')
    issue_id = models.PositiveIntegerField(null=True, blank=True)
    issue = generic.GenericForeignKey('issue_ct', 'issue_id')
class Issue(models.Model):
    scan = models.ForeignKey(Scan)

扫描创建一个问题,一个问题生成一些票证,我将问题作为工单表的外键。现在我有一个 Scan 对象,我想查询与此扫描相关的所有票证。我先试了这个:

tickets = Tickets.objects.filter(issue__scan=scan_obj)

这行不通。然后我试了这个:

issue = Issue.objects.get(scan=scan_obj)
content_type = ContentType.objects.get_for_model(Issue)
tickets = Tickets.objects.filter(content_type=content_type, issue=issue)

仍然不起作用。我需要知道如何在 django 中进行这些查询?谢谢。

您定义的Ticket.issue字段将帮助您从Ticket实例转到它附加到的Issue,但它不会让您倒退。您的第二个示例已接近,但您需要使用 issue_id 字段 - 您无法查询GenericForeignKey(它只是帮助您在有Ticket实例时检索对象)。试试这个:

from django.contrib.contenttypes.models import ContentType
issue = Issue.objects.get(scan=scan_obj)
tickets = Ticket.objects.filter(
    issue_id=issue.id,
    issue_ct=ContentType.objects.get_for_model(issue).id
    )
可以通过

创建与Ticket共享db_table的第二个模型来跨GenericForeignKey进行过滤。 首先将 Ticket 拆分为抽象模型和具体模型。

class TicketBase(models.Model):
    issue_ct = models.ForeignKey(ContentType, related_name='issue_content_type')
    issue_id = models.PositiveIntegerField(null=True, blank=True)
    class Meta:
        abstract = True
class Ticket(TicketBase):
    issue = generic.GenericForeignKey('issue_ct', 'issue_id')

然后创建一个模型,该模型也TicketBase . 此子类将具有所有相同的字段,但issue字段除外,后者被定义为ForeignKey。 添加自定义Manager可以将其过滤为单个ContentType

由于此子类不需要同步或迁移,因此可以使用type()动态创建。

def subclass_for_content_type(content_type):
    class Meta:
        db_table = Ticket._meta.db_table
    class Manager(models.Manager):
        """ constrain queries to a single content type """
        def get_query_set(self):
            return super(Manager, self).get_query_set().filter(issue_ct=content_type)
    attrs = {
        'related_to': models.ForeignKey(content_type.model_class()),
        '__module__': 'myapp.models',
        'Meta': Meta,
        'objects': Manager()
    }
   return type("Ticket_%s" % content_type.name, (TicketBase,), attrs)

相关内容

  • 没有找到相关文章

最新更新