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

Feature request: Allow AND operator to work with M2M relationship #144

Open
fcorallini opened this issue May 19, 2021 · 5 comments
Open

Comments

@fcorallini
Copy link

class Article(models.Model):
    ...
    tags = models.ManyToManyField('Tag', blank=True, verbose_name=_(u"Tags ..."))

With a simple model like this, I can't filter Articles with tag "Cars" AND "Lamborghini"

@sridhar562345
Copy link

class Article(models.Model):
    ...
    tags = models.ManyToManyField('Tag', blank=True, verbose_name=_(u"Tags ..."))

With a simple model like this, I can't filter Articles with tag "Cars" AND "Lamborghini"

I am also getting the same issue with M2M fieds

@asfaltboy
Copy link
Member

Could either of you contribute a failing test case to our test project & test cases? It will make fixing it much easier 🙏

@curtisstpierre
Copy link

curtisstpierre commented Feb 22, 2022

I'm working on building out a test case in your test suite for this issue but the gist of it that I can see is that when you use contains for an M2M relationship the AND clause doesn't get calculated properly.

example from my test system:

AdvancedFilter object (1) (AND: ['attributes__name__icontains', 'bar'], ['attributes__name__icontains', 'foo'])
this doesn't return the results that have attributes foo and bar, it returns nothing.

UPDATE: I see what the issue is, this is creating a Q object that is looking for a single relation where the name is foo and bar at the same time, that is why this doesn't work. In order to handle this scenario the way I found to do it is that it needs chained filters for each condition:

User.objects.filter(
Q(attributes__name__contains="foo")
).filter(Q(attributes__name__contains="bar"))

this ensures both attributes exist individually.

Here is an example of the issue:
https://stackoverflow.com/questions/55400746/django-q-queries-on-the-same-field

curtisstpierre added a commit to curtisstpierre/django-advanced-filters that referenced this issue Sep 14, 2022
@curtisstpierre
Copy link

Sorry just got back to this. Let me know if this PR covers what you want #174

@asfaltboy
Copy link
Member

asfaltboy commented Oct 8, 2022

Thank you for submitting the test @curtisstpierre, it clarifies what is requested, so I've now labelled the issue as an "enhancement".

We could add validation to prevent many-to-many fields to be accidentally used in this way while not fully implemented.

To fully support M2M field operations like the ones described above, we'd need to:

  1. Design a UI that will support M2M field, and clearly indicate to users. Perhaps a multi-option select field can work.
  2. Implement a schema for storing these "chained queries" in the AdvancedFilter.b64_query field.
  3. Add a few more cases, e.g. ensure we avoid duplicates (as described here).

I don't think I'll have time to work on this any time soon. That said, contributions are more than welcome

@asfaltboy asfaltboy changed the title AND operator not work with M2M relationship Feature request: Allow AND operator to work with M2M relationship Oct 8, 2022
asfaltboy pushed a commit to curtisstpierre/django-advanced-filters that referenced this issue Mar 28, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants