dabapps / django-readers

A lightweight function-oriented toolkit for better organisation of business logic and efficient selection and projection of data in Django projects.
https://www.django-readers.org
BSD 2-Clause "Simplified" License
186 stars 7 forks source link

Support overriding serializer arguments for automatically generated serializers #98

Closed j4mie closed 5 months ago

j4mie commented 5 months ago

For our schema generation support, we currently support automatic generation of serializer fields via model introspection:

spec = [
    "title",
]

# -->

class SomeSerializer(Serializer):
    title = CharField()

We also support overriding the auto-generated serializer field, using out:

spec = [
    "title" >> out(serializers.CharField(label="The title")),
]

# -->

class SomeSerializer(Serializer):
    title = CharField(label="The title")

However, in a large spec, if you wish to provide label and/or help_text (which are extremely useful during schema generation, as drf-spectacular uses them for the "title" and "description" OpenAPI attributes) to multiple fields in a large spec, using out is tedious, because you are essentially throwing away all of the clever automatic generation of serializer fields, and doing everything manually.

It would be nice if it were possible to provide extra keyword arguments to the default (automatically created) serializer fields.

As we already use the >> syntax for out, we could use the same idea. A couple of possibilities:

spec = [
    "title" >> kwargs(label="The title", help_text="Some help"),
]

Or perhaps just:

spec = [
    "title" >> label("The title") >> help_text("Some help"),
]

kwargs feels a little awkward because it implies that other kwargs than just label and help_text can be supplied - which is technically true, but none of the others are used by drf-spectacular in a read-only context, and remember the serializer we're generating here is only used for schema generation, not for actually serializing the objects (but then nothing else here is specifically tied to drf-spectacular, so maybe we should be thinking more generally?). On the other hand, providing label and help_text separately feels a bit awkward. Any other ideas? Any other arguments we might want to provide?

carltongibson commented 5 months ago

Nice idea.

…providing label and help_text separately feels a bit awkward.

That seems right to me. Too many functions.

I might feel the same about kwargs too 🤔

I wonder if out could be adjusted to something like, def out(field_or_dict=None, *, **kwargs) so that field_or_dict remains positional but optional, and then arbitrary kwargs could be passed if it were not provided?

The advantage there is just having one, familiar, but flexible function to learn, import, and use.

j4mie commented 5 months ago

I like that suggestion @carltongibson. Thanks!