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) 

扫描会产生一个问题,一个问题会产生一些票据,并且我将Issue作为一个外键给Ticket表。 现在我有一个扫描对象,我想查询所有与此扫描相关的票据。 我先试了一下:

 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字段 – 你不能在issue_id查询(当你有一个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)) 

通过db_table过滤可以通过创build与Ticket共享db_table的第二个模型。 首先将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(models.Model): issue = generic.GenericForeignKey('issue_ct', 'issue_id') 

然后创build一个也是TicketBase子类的模型。 这个子类将具有除了定义为ForeignKey issue以外的所有相同的字段。 添加自定义Manager可以将其过滤为仅一个ContentType

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

 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) 
Interesting Posts