Hi all, I've run into many situations during my time using Django where I've wanted to be able to express relations based on some other criteria than foreign key equality. A few examples: - descendants or children of a node in a tree structure - saved search terms to search results - a model containing a date range to timestamped items falling within that date range
Currently to do this kind of thing, you might write a getter which returns a queryset - think for example mptt's get_descendants(). But you don't get any of the nice things a real relation field gives you - you can't use that relationship in filters, you can't select/prefetch_related() or values(), there's no reverse relationship, etc. I've written a Relationship field[0] that lets you define relations in terms of arbitrary Q filters containing objects of a new type, L. An L is like an F, but represents a field on the "local" or "left" side of the relation, where the Q is filtering against the remote "to" side of the relation. For example, in a materialised path tree, this is how you might express descendants: class Node(models.Model): path = models.TextField() descendants = Relationship( "self", Q(path__startswith=L('path'), pk__ne=L('pk')), multiple=True, reverse_multiple=True, related_name='ascendants', ) Now you can use the descendants field like any other many-to-many field in all the places I mentioned above, but the relationship is based purely on prefix-matching on the path field. You also get an ascendants field on Node, which represents the path back to the root and can be used in the same way. I think this could make a nice new feature for Django. It would give a usability boost to anyone using MPTT or treebeard, for example. It works OK as a third-party library, but the current implementation relies heavily on undocumented ORM internals, and there are a few features I'd like to implement that are impractical without making some ORM changes. Thoughts/feedback/questions welcome! Thanks, Alex [0] https://github.com/alexhill/django-relativity -- You received this message because you are subscribed to the Google Groups "Django developers (Contributions to Django itself)" group. To unsubscribe from this group and stop receiving emails from it, send an email to django-developers+unsubscr...@googlegroups.com. To post to this group, send email to django-developers@googlegroups.com. Visit this group at https://groups.google.com/group/django-developers. To view this discussion on the web visit https://groups.google.com/d/msgid/django-developers/CA%2BKBOKzXDHJnO09Trkws2MJDu4DnOUsgxgA634xpCAKk1O5xJw%40mail.gmail.com. For more options, visit https://groups.google.com/d/optout.