django generic-foreign-key

django: ¿cómo hago una consulta basada en los campos de GenericForeignKey?



generic-foreign-key (2)

El campo Ticket.issue que ha definido lo ayudará a pasar de una instancia de Ticket al Issue que está adjunto, pero no le permitirá retroceder. Está cerca del segundo ejemplo, pero necesita usar el campo issue_id : no puede consultar en GenericForeignKey (solo le ayuda a recuperar el objeto cuando tiene una instancia de Ticket ). Prueba esto:

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

Soy nuevo en el uso de GenericForeignKey y no pude hacerlo funcionar en una declaración de consulta. Las tablas son aproximadamente como las siguientes:

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)

Un escaneo crea un problema, un problema genera algunos tickets y yo hice el Issue como una clave externa para la tabla de tickets. Ahora tengo un objeto de escaneo y deseo consultar todos los tickets relacionados con este escaneo. Intenté esto primero

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

que no funciona Entonces intenté esto:

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)

Todavía no funciona. ¿Necesito saber cómo hacer este tipo de consultas en django? Gracias.


El filtrado a través de un GenericForeignKey puede crear un segundo modelo que comparte la db_table con Ticket . Primer boleto dividido en un modelo abstracto y un modelo concreto.

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'')

Luego crea un modelo que también subclasifique TicketBase . Esta subclase tendrá todos los mismos campos, excepto el issue que, en cambio, se define como ForeignKey . Agregar un Manager personalizado permite filtrarlo a un solo ContentType .

Como esta subclase no necesita ser sincronizada o migrada, puede crearse dinámicamente usando 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)