carltongibson / django-filter

A generic system for filtering Django QuerySets based on user selections

Home Page:https://django-filter.readthedocs.io/en/main/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Nested choices variables not rendered correctly in OPTIONS response

mlissner opened this issue · comments

In freelawproject/courtlistener#1816, a user noted that when they make an OPTIONS request to our DRF API, they get a weird response. The response is in the filters section, and you can see the problem with the following command (it's a public API, no auth needed):

curl -X OPTIONS https://www.courtlistener.com/api/rest/v3/positions/27016/ | jq '.filters.position_type.choices'

That returns the following values:

 {
    "value": "Judge",
    "display_name": "(('act-jud', 'Acting Judge'), ('act-pres-jud', 'Acting Presiding Judge'),

    -----8<-----8<-----8<-----8<-----SNIP------8<-----8<-----8<-----8<-----8<-----8<-----8<

    'Vice Chief Judge'))"
  },
  {
    "value": "Attorney General",
    "display_name": "(('att-gen', 'Attorney General'), ('att-gen-ass', 'Assistant Attorney General'), ('att-gen-ass-spec', 'Special Assistant Attorney General'), ('sen-counsel', 'Senior Counsel'), ('dep-sol-gen', 'Deputy Solicitor General'))"
  },

I snipped out a bunch of characters in the middle, but the important part is that the display_name field for the judge value is a stringified nested tuple. This is because in the underlying model, we use named groups as defined in the Django docs, here.

The example from the docs is:

MEDIA_CHOICES = [
    ('Audio', (
            ('vinyl', 'Vinyl'),
            ('cd', 'CD'),
        )
    ),
    ('Video', (
            ('vhs', 'VHS Tape'),
            ('dvd', 'DVD'),
        )
    ),
    ('unknown', 'Unknown'),
]

In the OPTIONS response, the above example from the docs should get flattened to allow filtering on vinyl, cd, vhs, dvd, or unknown, but I believe it would instead offer values for Audio, Video, or Unknown. In my API, it should get flattened to provide att-gen, att-gen-ass, att-gen-ass-spec, etc.

Versions

[[package]]
name = "django-filter"
version = "2.4.0"

Thank you!

Hi @mlissner. Interesting

TBH It's not likely that I'd address this...

First step would be for you to make it work right in your project, and then we could see what a diff would look like.

Can you give me a pointer of where the options responses are generated? I can probably run with that.

Well it's in DRF (there's a bit in the docs for it). Then that'll call into the filtering backend.