【问题标题】:Including child resources in a Django Tastypie API在 Django Tastypie API 中包含子资源
【发布时间】:2011-12-10 13:46:03
【问题描述】:

我正在为 REST API 计划一个包含 Django 和 Tastypie 的站点,并且 我很难找出“正确”的方式来包括 返回资源中的子资源。

作为沙盒,我制作了一个带有 Ticket 模型和 TicketComment 的小应用 模型,其中 cmets 属于一张票。我看了美味食谱 嵌套资源的配方(http://django-tastypie.readthedocs.org/en/latest/cookbook.html#nested-resources), 但我很难理解为什么我应该这样做。下面的代码 使用 django.forms.models.model_to_dict() 将 cmets 放入票证中, 但我想这里一定有一个“陷阱”。

我是否有理由不做我现在正在做的事情?还有,有没有 比食谱中列出的更清洁的感觉模式?

型号如下:

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

资源如下:

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

输出如下:

{
   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"
}

【问题讨论】:

    标签: python django api rest tastypie


    【解决方案1】:

    【讨论】:

    • 谢谢,这更有意义,但是我得到的只是子 cmets 的 URL。如果我想要序列化资源,有没有一种干净的方法来获取它们?
    • 在声明中使用 full=True 参数
    • 完美,正是我想要的。谢谢!
    【解决方案2】:

    你能发布你的解决方案吗?

    我有相同的用例/模型(在“子表”中建立的外键关系指向父表)但无法解决。

    我看到的解决方案是将此行添加到您的 TicketResource 一个不在元子类中的类级别:

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

    然后可能也将其添加到 TicketCommentResource,再次在类级别:

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

    但我总是收到错误消息,即我的父对象资源(在您的示例 TicketResource 中)没​​有属性“ticket”,这是发送到 ToManyField 的第二个术语。

    我尝试了很多次,但似乎无法获得获胜组合。 您最初发布的解决方案有效,但正如您自己指出的那样并不理想。

    谢谢!

    【讨论】:

    • 想将此添加为评论,但没有选项。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-17
    • 1970-01-01
    • 1970-01-01
    • 2012-06-03
    • 2012-07-02
    • 2011-12-02
    相关资源
    最近更新 更多