Search code examples
djangotastypie

How to get tastypie to do a reverse lookup on foreign key?


I have two django models: biology and occurrence. They have a one-to-one relationship. The biology model has a foreign key to occurrence, and the tastypie biologyResource follows this relationship and displays the corresponding occurrence data correctly. I am trying to get reverse lookups to work in the API. When I try to access the occurrenceResource, I get an error

"error: "The model '2' has an empty attribute 'occurrence' and doesn't allow a null value.""

My tastypie resource classes look like this

class biologyResource(ModelResource):
    occurrence = fields.ToOneField("API.API_resources.occurrenceResource", "occurrence")
    class Meta:
        queryset = biology.objects.all()
        resource_name = 'biology'


class occurrenceResource(ModelResource):
    biology = fields.ToOneField("API.API_resources.biologyResource", "id", full=True)
    class Meta:
        queryset = occurrence.objects.all()
        resource_name = 'occurrence'

I have seen some similar stackoverflow questions, but they mostly deal with many-to-many relationships. Any ideas?


Solution

  • There is one rule very useful in such cases. Almost always the attribute of resource field is an attribute of the model field.

    if your model has field:

    my_field = model.WhateverField()

    So Resource definition will have to have:

    my_field = fields.WhateverField("Whatever", attribute="my_field")

    How do you access biology through occurrence?

    >>> biology_object.occurrence # I assume your model name is `Occurrence`
    

    And other way:

    >>> occurrence_object.biology # I assume your model name is `Biology`
    

    So occurrence and biology are properties of model in other words they are attributes.

    class biologyResource(ModelResource):
        occurrence = fields.ToOneField("API.API_resources.occurrenceResource", attribute="occurrence")
        class Meta:
            queryset = biology.objects.all()
            resource_name = 'biology'
    
    
    class occurrenceResource(ModelResource):
        biology = fields.ToOneField("API.API_resources.biologyResource", attribute="biology", full=True)
        class Meta:
            queryset = occurrence.objects.all()
            resource_name = 'occurrence'
    

    In case of trouble copy paste your models.