Search code examples
djangoresttastypie

django-tastypie and many to many "through" relationships


In Django and Tastypie I'm attempting to figure out how to properly deal with Many to Many "through" relationships, like those found here: https://docs.djangoproject.com/en/dev/topics/db/models/#extra-fields-on-many-to-many-relationships

Here are my sample models:

class Ingredient(models.Model):
    name = models.CharField(max_length=100)
    description = models.TextField()

class RecipeIngredients(models.Model):
    recipe = models.ForeignKey('Recipe')
    ingredient = models.ForeignKey('Ingredient')
    weight = models.IntegerField(null = True, blank = True)

class Recipe(models.Model):
    title = models.CharField(max_length=100)
    ingredients = models.ManyToManyField(Ingredient, related_name='ingredients', through='RecipeIngredients', null = True, blank = True)

Now my api.py file:

class IngredientResource(ModelResource):
    ingredients = fields.ToOneField('RecipeResource', 'ingredients', full=True)

    class Meta:
        queryset = Ingredient.objects.all()
        resource_name = "ingredients"


class RecipeIngredientResource(ModelResource):
    ingredient = fields.ToOneField(IngredientResource, 'ingredients', full=True)
    recipe = fields.ToOneField('RecipeResource', 'recipe', full=True)

    class Meta:
        queryset= RecipeIngredients.objects.all()


class RecipeResource(ModelResource):
    ingredients = fields.ToManyField(RecipeIngredientResource, 'ingredients', full=True)

class Meta:
    queryset = Recipe.objects.all()
    resource_name = 'recipe'

I'm trying to base my code on this example: http://pastebin.com/L7U5rKn9

Unfortunately, with this code I get this error:

"error_message": "'Ingredient' object has no attribute 'recipe'"

Does anyone know what's happening here? Or how I can include the name of the ingredient in the RecipeIngredientResource? Thanks!

EDIT:

I may have found the error myself. ToManyField should be directed toward Ingredient and not RecipeIngredient. I'll see if this does the job.

EDIT:

New error.. any ideas? The object '' has an empty attribute 'title' and doesn't allow a default or null value.


Solution

  • You mentioned:

    I may have found the error myself. ToManyField should be directed toward Ingredient and not RecipeIngredient. I'll see if this does the job.

    There's a better approach though [Tastypie M2M](http://blog.eugene-yeo.in/django-tastypie-manytomany-through.html) (old blog is offline: https://github.com/9gix/eugene-yeo.in/blob/master/content/web/django-tastiepie-m2m.rst)

    In short summary, Instead of ToManyField to Ingredients, I use ToManyField toward the ThroughModel. And customize the attribute kwargs to be a callback function that return the ThroughModel Queryset.

    Update (2014 Apr)

    This answer is made long ago. Not sure if it is still useful.