Support source='some_method' for HyperlinkedRelatedField. #2690
The use case is simple. Fore example, you have a model
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=...)
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.
@tomchristie I added a test case for PK relations and also a possible fix to show where the problem was introduced (it was working on DRF<3.x)
To answer your questions:
Okay, seems reasonable enough.
Given the narrow scope of the change, I feel like the test changes (eg changing the test model) are more detrimental than we'd like. I'd suggest that we either: (1) try to limit the test scope so that eg the model they use is contained in the test itself. Or (2) just drop the tests - the code is clearly more correct that it was previously, and even just a code comment of
Either (1) or (2) would be acceptable to me.
(Motivation for keeping the test scope limited is that we may one day want to refactor and clean up the gnarly relational tests, and right now this'd add more work to achieving that)
@tomchristie I usually prefer tests over code comments, but in this case I just dropped the tests. It felt wrong to duplicate the two related models and have them self-contained in each test case.
I removed the model changes and the tests, and added a code comment on the edge case. Please take another look.