如何使用Tastypie在JSON中内联ManyToMany字段?

时间:2014-02-23 03:36:40

标签: python json django tastypie

我刚刚学习了TastyPie,并对ManyToManyFields在ModelResources中的工作方式感到困惑。具体来说,我正在尝试使用 image 资源来内联其标记字段(多对多关系)。

models.py

from django.db import models

class Image(models.Model):
    filename    = models.CharField(max_length=200, unique=True)
    added       = models.DateTimeField(auto_now_add=True) 
    modified    = models.DateTimeField(auto_now=True)
    tags        = models.ManyToManyField('Tag', related_name='+', null=True)
    def __unicode__(self):
        return self.filename

class Tag(models.Model):
    name        = models.CharField(max_length=200, unique=True)
    def __unicode__(self):
         return self.name

api.py

from tastypie import fields
from tastypie.resources import ModelResource

from image_browser.models import Image, Tag

class ImageResource(ModelResource):
    tags = fields.ManyToManyField("image_browser.api.TagResource", 'tags', 
        null=True, full=True, related_name='image')

    class Meta:
        queryset = Image.objects.all()
        resource_name = 'image'
        fields = ['filename', 'tags']

class TagResource(ModelResource):
    class Meta:
        queryset = Tag.objects.all()
        fields = ['name']
        resource_name = 'tags'

我正在尝试了解如何拥有如下资源列表:

{
    meta: {
    limit: 20,
    next: "/image_browser/v1/image/?offset=20&limit=20&format=json",
    offset: 0,
    previous: null,
    total_count: 34
},
objects: [
{
    filename: "10.jpg",
    resource_uri: "/image_browser/v1/image/2/",
    tags: ['B&W','portrait']
},
...

显而易见的是“内联”标签 - 我不太关心它是否作为完整标签资源的列表或扩展JSON。但是,返回的JSON中的“tags”字段始终是一个空的[]数组。我尝试过的东西,没有任何作用。我是否需要返回并添加ImageTagModel类和ImageTagResources以显式提供“通过”表?我不指望魔法,但令人沮丧的是如何不干这一切;我希望我不必再次迁移我的数据库;我想知道为什么这个看似常见的案例没有在文档中的任何地方拼写出来,除非我遗漏了一些东西。

我是新手,所以也许我错过了一些明显的东西?我已经阅读了其他几个Q& As相关问题,但这些问题都没有帮助我完成简单的工作。

1 个答案:

答案 0 :(得分:1)

我已运行您的代码并得到以下回复

{"meta": 
{"limit": 20, "next": null, "offset": 0, "previous": null, "total_count": 1}, 
"objects": [
{"filename": "10.jpg", "resource_uri": "/api/image/1/", 
"tags": [{"name": "portrait", "resource_uri": "/api/tags/1/"}, 
  {"name": "B&W", "resource_uri": "/api/tags/2/"}]}]}

所以我认为你在Tastypie中的定义是正确的。您确定已将对象正确添加到数据库吗?

我的测试代码:

    im = Image(filename='10.jpg')
    im.save()
    tags = [Tag(name='portrait'),Tag(name='B&W')]
    for tag in tags:
        tag.save()
    im.tags.add(*tags)
    resp = self.client.get('/api/image/')