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

JSONField with ModelMultipleChoiceFilter #1100

Closed
Sqvall opened this issue Jul 11, 2019 · 2 comments
Closed

JSONField with ModelMultipleChoiceFilter #1100

Sqvall opened this issue Jul 11, 2019 · 2 comments

Comments

@Sqvall
Copy link

Sqvall commented Jul 11, 2019

Hello.
I read a lot Issue, but i don't understand why my filter does not work?
I have model:

class Product(models.Model):
    name = models.CharField(max_length=120)
    properties = JSONField(default=dict, blank=True, null=True)

and Filter

class ProductFilter(FilterSet):
    color = filters.ModelMultipleChoiceFilter(
        queryset=Product.objects.values_list('properties__color', flat=True).distinct(),
        field_name='properties',
        to_field_name='properties__color__contains',
        conjoined=True,
        )

    class Meta:
        model = Product
        fields = {
            'color': 'color__contains',
        }

My item

{
    "id": 10,
    "name": "Test_3",
    "properties": {
        "color": "Black",
        "invertor technology": false,
        "service area, m²": 24
    },
},

But i have this SQL query

SELECT ••• FROM "products_product" WHERE ("products_product"."properties" #> ARRAY['color','contains']) IN ('"Black"')

If i change this:

to_field_name='properties__color'

I have:

SELECT ••• FROM "products_product" WHERE ("products_product"."properties" -> 'color') IN ('"Black"')

And i have Error: 'str' object has no attribute 'properties__color'
How i can have:

SELECT ••• FROM "products_product" WHERE ("products_product"."properties" -> 'color') @> '"Black"'

Or may be you tell me what SQL query more correct?
If i use this CharFilter:

color2 = filters.CharFilter(
        field_name='properties',
        lookup_expr='color__contains',
    )

All work wonderful, but I need have choose more one values this filter.

@rpkilby
Copy link
Collaborator

rpkilby commented Jul 11, 2019

There are a few things wrong here

  • ModelMultipleChoiceFilter is intended to work across foreign keys.
    For example, find Articles with the given Tags.
  • to_field_name is meant to correspond with ForeignKey.to_field.
  • field_name should only contains the model field. lookup_expr should contain the lookup expressions (like contains).

It looks like you probably want to use AllValuesMultipleFilter, although I'm not entirely certain if it will work with JSONFields. Try:

class ProductFilter(FilterSet):
    color = filters.AllValuesMultipleFilter(
        field_name='properties__color',
        lookup_expr='contains,
    )

@Sqvall
Copy link
Author

Sqvall commented Jul 11, 2019

Oh it's work amazing, I spend this problem three day trying to sort out this problem.
Thank you so much!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants