carltongibson / django-filter

A generic system for filtering Django QuerySets based on user selections
https://django-filter.readthedocs.io/en/main/
Other
4.46k stars 769 forks source link

please give me one small example about QueryArrayWidget #1090

Closed zhimingzhang123 closed 3 years ago

zhimingzhang123 commented 5 years ago

I read the issue #1030, But I can't use it, In the document, I didn't find about QueryArrayWidget, please give me one small example, I need QueryArrayWidget , It does what I need. thanks

zhimingzhang123 commented 5 years ago

@rpkilby I need your help, thanks

rpkilby commented 5 years ago

Hi @zhimingzhang123. The original PR is #548, but it's not something that I've ever used.

I assume all you need to do is pass the widget to the filter. Any non-filter arguments are passed on to the underlying Django form field (e.g., widget). something like

from django_filters import FilterSet, filters, widgets

class MyFilterSet(FilterSet):
    my_field = filters.MultipleChoiceFilter(
        'other',
        'arguments...', 
        widget=widgets.QueryArrayWidget,
    )
zhimingzhang123 commented 5 years ago

@rpkilby @pySilver There seems to be a way that doesn't work

python3.6
django==2.1
djangorestframework==3.9
django-filter==2.1

models.py

NAME_TYPE = (
  ("apple", "Apple"),
  ("banana", "Banana")
)
class Production(models.Model):
    name = models.CharField(choice=NAME_TYPE, max_length=30)

filters.py

from django_filters import FilterSet, filters, widgets
from .models import Production, NAME_TYPE
class ProdcutionFilter(FilterSet):

    s_name = filters.MultipleChoiceFilter(
        field_name='name',
        choices=TYPE_MAP,
        widget=widgets.QueryArrayWidget
    )

    class Meta:
        model = Production
        fields = ['s_name']

views.py

from rest_framework.viewsets import ModelViewSet
class ProdictionView(ModelViewSet):

    queryset = Production.objects.all()
    serializer_class = ProductionSerializer
    filter_backends = (django_filters.rest_framework.DjangoFilterBackend,)
    filterset_class = ProdcutionFilter

test result

http://localhost:8000/production/?s_name=apple&s_name=banana    OK
http://localhost:8000/production/?s_name[]=apple    OK
http://localhost:8000/production/?s_name=apple,banana  FAILED

ERROR is
{
    "s_name": [
        "Select a valid choice. apple,banana is not one of the available choices."
    ]
}

I don't know why one of them went wrong, I'm trying to print in the code

    def value_from_datadict(self, data, files, name):
        print(type(data))    # the type is QueryDict
        if not isinstance(data, MultiValueDict):
            print("---------")  # this print has no executed
            for key, value in data.items():
                # treat value as csv string: ?foo=1,2
                if isinstance(value, str):
                    data[key] = [x.strip() for x in value.rstrip(',').split(',') if x]
            data = MultiValueDict(data)

        values_list = data.getlist(name, data.getlist('%s[]' % name)) or []

If you have free time, I hope you can help me, thanks.

rpkilby commented 5 years ago

See https://github.com/carltongibson/django-filter/pull/586#issuecomment-506477277. Ah, just noticed #1047, which seems to be the same issue.

sergei-maertens commented 4 years ago

Confirmation from my end, CSV parsing is indeed broken.

carltongibson commented 3 years ago

Duplicate of #1047

Rjevski commented 1 year ago

Has anyone managed to get this to work? I'd like to get a similar example as in https://github.com/carltongibson/django-filter/issues/1090#issuecomment-506228492 working, but even implementing the fix in https://github.com/carltongibson/django-filter/issues/1047 (and passing the fixed class as widget kwarg to MultipleChoiceFilter) it does not work and appears to be treating comma-separated values as a single choice (which then throws the "not a valid choice" error?

carltongibson commented 1 year ago

QueryArrayWidget is for PHP style ?key[]=value1&key[]=value2 multiple params (using the PHP array syntax in the query string).

I don't think that makes much sense with CSV params, which would be `?key=value1,value2.

If you want to open a fresh issue, explaining it all again clearly, I'm happy to look, but I'm not really minded to go back through the history here, given that it looks like misunderstandings really.

Rjevski commented 1 year ago

Cool, sounds good. I'll write up a fresh issue with a minimal example.

On 22 Mar 2023, at 16:42, Carlton Gibson @.***> wrote:

QueryArrayWidget is for PHP style ?key[]=value1&key[]=value2 multiple params (using the PHP array syntax in the query string). I don't think that makes much sense with CSV params, which would be `?key=value1,value2. If you want to open a fresh issue, explaining it all again clearly, I'm happy to look, but I'm not really minded to go back through the history here, given that it looks like misunderstandings really. — Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you commented.Message ID: @.***>