سؤال

I'm just learning TastyPie and am confused about how ManyToManyFields work in ModelResources. Specifically I'm trying to get image resources to inline their tags field (a many to many relationship).

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'

I'm trying to understand how to have a resource listing like:

{
    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']
},
...

The salient thing is to "inline" tags -- I don't much care if its as a list or as expanded JSON for the full tag resources. However the 'tags' field in the returned JSON is always an empty [ ] array. I have tried may things, nothing works. Am I required to go back and add the ImageTagModel classes and ImageTagResources to explicitly provide the "through" table? I don't expect magic, but it's frustrating how not DRY all this is; I wish I didn't have to migrate my database again; and I am wondering why this seemingly common case is not spelled out anywhere in the docs, unless I'm missing something.

I'm new to this so maybe I'm missing something obvious? I have read several other Q&As on related questions, none of which have helped me get my simple case to work.

هل كانت مفيدة؟

المحلول

I've ran your code and got the following response

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

So I think your definitions in Tastypie are correct. Are you sure you've added the objects properly to the DB?

My test code:

    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/')
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top