Incluyendo recursos secundarios en una API de Django Tastypie

Estoy planeando un sitio con Django y Tastypie para la API REST, y me cuesta mucho encontrar la manera “correcta” de incluir recursos secundarios en un recurso devuelto.

Como caja de arena, hice una pequeña aplicación con un modelo de Ticket y un modelo de TicketComment, donde los comentarios pertenecen a un ticket. Miré la receta del libro de cocina de Tastypie en recursos nesteds (http://djangotastypie.readthedocs.org/en/latest/cookbook.html#nested-resources), pero me cuesta entender por qué debo hacer eso . El siguiente código utiliza django.forms.models.model_to_dict () para incluir los comentarios en el ticket, pero creo que debe haber un “gotcha” aquí en algún lugar.

¿Hay alguna razón por la que no debería hacer lo que estoy haciendo ahora? Además, ¿existe un patrón de sentimiento de limpieza más amplio que el que se indica en el libro de cocina?

Los modelos son los siguientes:

# tickets/models.py from django.db import models class Ticket(models.Model): title = models.CharField(max_length=200) create_ts = models.DateTimeField(auto_now_add=True) submitter_email = models.EmailField() PRIORITY_CHOICES = ( ('H', 'High'), ('M', 'Medium'), ('L', 'Low'),) priority = models.CharField(max_length=1, choices=PRIORITY_CHOICES) description = models.TextField() STATUS_CHOICES = ( ('NEW', 'New & Unclaimed'), ('WIP', 'Work In Progress'), ('RES', 'Resolved'), ('CLS', 'Closed'),) status = models.CharField(max_length=3, choices=STATUS_CHOICES) def __unicode__(self): return "" % (self.id, self.title,) class TicketComment(models.Model): ticket = models.ForeignKey(Ticket) comment_ts = models.DateTimeField(auto_now_add=True) commenter_email = models.EmailField() comment = models.TextField() def __unicode__(self): return "" % (self.ticket.id, self.id,) 

Los recursos son los siguientes:

 # tickets/api.py from tastypie import fields from tastypie.resources import ModelResource from tickets.models import Ticket, TicketComment from django.forms.models import model_to_dict class TicketResource(ModelResource): class Meta: queryset = Ticket.objects.all() resource_name = 'ticket' def dehydrate(self, bundle): comments = TicketComment.objects.filter(ticket=bundle.data['id']) bundle.data['comments'] = [model_to_dict(c) for c in comments] return bundle class TicketCommentResource(ModelResource): ticket = fields.ForeignKey(TicketResource, 'ticket') class Meta: queryset = TicketComment.objects.all() resource_name = 'comment' 

La salida es la siguiente:

 { comments: [ { comment: "This is the first comment.", commenter_email: "me@example.com", id: 1, ticket: 1 }, { comment: "This is the second comment.", commenter_email: "me@example.com", id: 2, ticket: 1 } ], create_ts: "2011-10-17T15:55:11.372000", description: "This is the first ticket.", id: "1", priority: "M", resource_uri: "/api/v1/ticket/1/", status: "NEW", submitter_email: "me@example.com", title: "First Ticket" } 

¿Puedes publicar tu solución?

Tengo los mismos casos / modelos de uso (un envío de relación de clave externa establecido en la “tabla secundaria” que apunta a la tabla principal) pero no puedo resolverlo.

La solución que he visto es agregar esta línea a su TicketResource a nivel de clase NO dentro de la subclase meta:

 comments = fields.ToManyField('TicketCommentResource', 'ticket', full=True) 

Entonces posiblemente también agregue esto a TicketCommentResource, nuevamente en el nivel de clase:

 event = fields.ForeignKey('TicketResource', 'event') 

Pero siempre recibo el error de que mi recurso de objeto principal (en su ejemplo, TicketResource) no tiene el atributo ‘ticket’, que es el segundo término enviado a ToManyField.

He intentado jugar mucho con esto pero parece que no puedo obtener el combo ganador. La solución que originalmente publicaste funciona, pero como tú mismo lo señalaste no es ideal.

¡Gracias!