vitalik / django-ninja

💨 Fast, Async-ready, Openapi, type hints based framework for building APIs
https://django-ninja.dev
MIT License
7k stars 420 forks source link

Implementing object-esque query params #618

Open jmduke opened 1 year ago

jmduke commented 1 year ago

(I suspect this is related to https://github.com/vitalik/django-ninja/issues/86.)

I want to implement arbitrary key/value filtering. A toy example of this:

class ObjectFilter(Schema):
  metadata: dict[str, str] # `/objects?metadata[foo]=bar`

@router.get('/')
def list_objects(request, filters: ObjectFilter = Query(...))

This doesn't appear to work out of the box, and I've tried various different approaches. I suspect the issue is because the 'key' presented to django-ninja is metadata[foo], but I can't actually figure out where to plug into the framework to override the translation of the query parameters into the parsed input that's passed to the Schema. Any guidance? Thanks!

OtherBarry commented 1 year ago

You could write your own logic to parse data in an alternate format. a JSON string or list of JSON strings seem to be the easiest. See here for some examples.

Alternatively if there's a fixed set of possible values for filters, you could define your own schema dynamically using pydantic's create_model. I've written a filter decorator that does this here

jmduke commented 1 year ago

Thank you for the links @OtherBarry! It seems like the escape hatch I really want is something like fastapi's Depends — if I'm understanding it correctly, it lets me declare an arbitrary Request → obj mapping and pass it into the view function. Does Django-ninja have any such similar construct?

OtherBarry commented 1 year ago

The dependency injection aspect of FastAPI was intentionally excluded from Django Ninja, so there's nothing directly equivelant.

There's a few ways to do it:

jmduke commented 1 year ago

Thank you! (I ended up going with the last option.)

LaundroMat commented 1 year ago

@jmduke Would you care to share your code? I'm in a similar situation and don't really know where to begin.