Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support symmetrical ManyToMany relationships #1612

Open
laggron42 opened this issue May 12, 2024 · 2 comments
Open

Support symmetrical ManyToMany relationships #1612

laggron42 opened this issue May 12, 2024 · 2 comments
Labels
enhancement New feature or request

Comments

@laggron42
Copy link

laggron42 commented May 12, 2024

Django ORM has support for what they call symmetrical relationships, that is a ManyToMany relationship on self. (see here https://docs.djangoproject.com/en/dev/ref/models/fields/#django.db.models.ManyToManyField.symmetrical)

For example, if you want a ManyToMany relation for friends and you want the logic to be "if I am your friend, then you are my friend", you would use a symmetrical relation. That way, there is no related attribute generated on the other class, and for checking the friend status, you only have to look up one field instead of both.

Example

class User(models.Model):
  name = fields.TextField()
  friends = fields.ManyToMany("models.User", symmetrical=True)

>>> u1 = await User.create("Bob")
>>> u2 = await User.create("Alice")
>>> await u1.friends.add(u2)
>>> await u1.friends.filter(id=u2.id).exists()
True
>>> # bi-directional
>>> await u2.friends.filter(id=u1.id).exists()
True

I can try to contribute this, but I want the confirmation from a maintainer first

@abondar
Copy link
Member

abondar commented May 13, 2024

Hi!

I am not sure, but if understand correct - we already support that:

You can see example at
https://github.com/tortoise/tortoise-orm/blob/develop/examples/relations_recursive.py#L24

Please write if I am wrong on what's issue

@abondar abondar closed this as completed May 13, 2024
@laggron42
Copy link
Author

Hi, thanks for your response!

The example you linked shows recursdive relations, but they're not symmetrical. talks_to and gets_talked_to are two different sets despite being the same relation, if it's symmetrical then both sets should be identical.

Once again, I like the example of "If X is my friend, then I am the friend of X". If talks_to was symmetrical, this would work:

>>> await _1.talks_to.add(_2, _1_1_1, loose)
>>> await _1.talks_to.all()
[<Employee: 4>, <Employee: 6>, <Employee: 2>]
>>> await _2.talks_to.all()  # right now this returns an empty list
[<Employee: 3>]

@abondar abondar reopened this May 18, 2024
@abondar abondar added the enhancement New feature or request label May 18, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants