Support source='some_method' for HyperlinkedRelatedField. by delinhabit · Pull Request #2690 · encode/django-rest-framework (original) (raw)

A callable source is an allowed argument type for any Field, including HyperlinkedRelatedField. Since the docs are not prohibiting this usage scenario I just assumed that I can use a callable source for a HyperlinkedRelationField like I can use it for other field types.

The use case is simple. Fore example, you have a model Conversation with two foreign keys to a Person model: provider and requester. In the API I want to expose the recipient for the Conversation which is computed using Conversation.get_recipient() based on who created the conversation. The serializer is something along the lines:

class Conversation(models.Model): provider = models.ForeignKey(Person) requester = models.ForeignKey(Person) sender = models.ForeignKey(Person) # enforced logically to be one of (provider, requester)

def get_recipient(self):
    if self.sender == self.provider:
        return self.requester
    else:
        return self.provider

class ConversationSerializer(serializers.ModelSerializer): sender = serializer.HyperlinkedRelatedField(view_name=...) recipient = serializer.HyperlinkedRelatedField(source='get_recipient', view_name=...)

Basically recipient is computed dynamically based on other fields on the instance, but conceptually it's still a relation. I think we should be able to use a HyperlinkedRelatedField for this purpose.

If we don't want to support this we should at least add this to the docs that a related field can be used only on actual relations and not on methods that return a relation.

Thanks!