Hello Alex!

Thanks for your work on this project, this is definitely something that I 
believe would be useful in Django's core based on the number of times I 
implemented a filtered queryset getter on Models.

I'm not totally sold on the API but having an analog of what ForeignObject 
is to ForeignKey for ManyToManyField would definitely be useful.

>From what I can see in relativity.fields[0] most of the additional logic 
revolves around the extra filtering capabilites through Restriction.

Do you have an idea of what the fields.related inheritance chain would look 
like if it was part of core? I feel like having Relation(RelatedField), 
ForeignObject(Relation), ManyToManyField(Relation) and adding the filtering 
logic to Relation could work but I'd be interested to hear what you think 
here. FWIW Anssi implemented something similar[1] for reverse unique 
relationship before FilteredRelation() was introduced.

In a sense Relation would be form of virtual field like ForeignObject since 
it's not in charge of any database field handling.

Simon

[0] 
https://github.com/AlexHill/django-relativity/blob/3802608c64e86c62ab6268efc37a3f5ca8539221/relativity/fields.py
[1] https://github.com/akaariai/django-reverse-unique



Le jeudi 30 août 2018 11:38:16 UTC-4, Alex Hill a écrit :
>
> 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 [email protected].
To post to this group, send email to [email protected].
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/c87af098-baa4-4d45-9a4b-757166b41734%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to