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.

Reply via email to