2011-10-19 26 views
8

Tôi đang lập kế hoạch một trang web với Django và Tastypie cho API REST và Tôi đang gặp khó khăn trong việc tìm ra cách "đúng" để bao gồm tài nguyên con trong nguồn.Bao gồm tài nguyên trẻ em trong một API Django Tastypie

Là một hộp cát, tôi đã tạo một ứng dụng nhỏ với mô hình Vé và mô hình Vé , nơi nhận xét thuộc về vé. Tôi đã xem công thức nấu ăn Tastypie Cookbook về tài nguyên lồng nhau (http://django-tastypie.readthedocs.org/en/latest/cookbook.html#nested-resources), nhưng tôi đang gặp khó khăn khi hiểu tại sao tôi nên làm việc đó đi. Mã bên dưới sử dụng django.forms.models.model_to_dict() để nhận các nhận xét vào vé, nhưng tôi nghĩ rằng phải có một "địa chỉ" ở đâu đó.

Có lý do nào mà tôi không nên làm những gì tôi đang làm bây giờ không? Ngoài ra, có mẫu sạch hơn cho cảm giác này hơn những gì được liệt kê trong sách dạy nấu ăn không?

Models như sau:

# 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 "<Ticket:%d:%s>" % (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 "<TicketComment:%d:%d>" % (self.ticket.id, self.id,) 

Tài như sau:

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

Output như sau:

{ 
    comments: [ 
     { 
      comment: "This is the first comment.", 
      commenter_email: "[email protected]", 
      id: 1, 
      ticket: 1 
     }, 
     { 
      comment: "This is the second comment.", 
      commenter_email: "[email protected]", 
      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: "[email protected]", 
    title: "First Ticket" 
} 

Trả lời

14

Bạn đang tìm kiếm các lĩnh vực có liên quan: http://django-tastypie.readthedocs.org/en/latest/fields.html#relationship-fields

+0

Cảm ơn, điều này có ý nghĩa hơn rất nhiều, tuy nhiên tất cả những gì tôi nhận được là URL cho nhận xét của trẻ. Nếu tôi muốn các tài nguyên được tuần tự hóa thay vào đó, có cách nào sạch sẽ để lấy chúng không? – Doug

+9

sử dụng đối số đầy đủ = True trong khai báo của bạn –

+0

Hoàn hảo, chính xác những gì tôi muốn. Cảm ơn! – Doug

1

Bạn có thể đăng giải pháp của mình không?

Tôi có cùng trường hợp/mô hình sử dụng (một tàu quan hệ nước ngoài được thiết lập trong "bảng con" chỉ trở lại bảng cha) nhưng không thể giải quyết nó.

Các giải pháp tôi đã thấy là để thêm dòng này vào TicketResource bạn một mức lớp KHÔNG trong lớp con meta:

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

Sau đó có thể cũng thêm video này vào TicketCommentResource, một lần nữa ở cấp lớp:

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

Nhưng tôi luôn nhận được lỗi mà tài nguyên đối tượng cha mẹ của tôi (trong ví dụ TicketResource) của bạn không có thuộc tính 'ticket' là thuật ngữ thứ hai được gửi đến ToManyField.

Tôi đã cố gắng chơi với điều này rất nhiều nhưng dường như không thể có được kết hợp chiến thắng. Giải pháp ban đầu mà bạn đã đăng hoạt động nhưng bản thân bạn đã chỉ ra rằng nó không lý tưởng.

Cảm ơn!

+0

Muốn thêm nhận xét này làm nhận xét nhưng không có tùy chọn. –

Các vấn đề liên quan