Search code examples
djangotastypie

Django Tastypie Reference the Same ForeignKey Model More Than Once


Is there a way to reference the same ForeignKey model/resource more than once in Tastypie?

Assume the models:

class Case(models.Model):
    name = models.CharField(max_length=10)

class Interaction(models.Model):
    case = models.ForeignKey(Case, related_name="interaction_cases")
    type = models.CharField(max_length=2, choices=TYPE_CHOICES)

Assume the TastyPie resources:

class CaseResource(ModelResource):
    type_one_interactions = fields.ManyToManyField('TypeOneInteractionFullResource', 'interaction_cases', null=True, full_list=True, full=True)
    type_two_interactions = fields.ManyToManyField('TypeTwoInteractionFullResource', 'interaction_cases', null=True, full_list=True, full=True)

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

class TypeOneInteractionResource(ModelResource):
    case = fields.ForeignKey(Case,'case')

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

    def get_object_list(self, request):
        return super(TypeOneInteractionResource, self).get_object_list(request).filter(type='A')

class TypeTwoInteractionResource(ModelResource):
    case = fields.ForeignKey(Case,'case')

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

    def get_object_list(self, request):
        return super(TypeTwoInteractionResource, self).get_object_list(request).filter(type='B')

Basically I am trying to create a single resource with two reverse resources to the same model with different data. When I access the CaseResource I see both TypeOneInteractionResource and TypeTwoInteractionResource in the result, but the data is not being filtered correctly.

I assume it has something to do with the "related_name" being the same and the way TastyPie does model joining internally. Has anybody been successful doing this? Is it even possible?


Solution

  • The reason is because get_object_list is not called at all when dehydrating the ToManyField for related resources (see https://github.com/toastdriven/django-tastypie/blob/master/tastypie/fields.py#L780).

    Instead, you'd want to use the dehydrate_type_one_interactions and dehydrate_type_two_interactions methods on the CaseResource.

    On the other hand, you can provide properties on the Case model that would return desired QuerySets and use those properties for attribute names in ManyToManyFields.