-
Notifications
You must be signed in to change notification settings - Fork 273
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
In a OpenApiSerializerFieldExtension, how to extend from the default output? #426
Comments
i'm sry but you now used up your free questions. this is for legitimate issues and bugs, and i'm not stackoverflow. your other issue #425 indicated that you did not even try to find out yourself. i'm happy to help with tricky issues, but only after i have seen some effort on your part. i have only limited time doing this for free. def map_serializer_field(self, auto_schema, direction):
schema = auto_schema._map_serializer_field(self.target, direction)
schema["example"] = "2021-06-10"
return schema |
Thanks for the answer. I assure you that I have spent already one full working day setting up this library and converting all of our existing customizations to it. Maybe I'm dumb, maybe the task was a bit ambitious, but there is no lack of effort. And I'm getting close. If you're interested in my attempts before opening the issue, I did try I would humbly suggest updating the doc for OpenApiSerializerFieldExtension, with this more full-featured example. |
@tfranzel actually, this solution creates an infinite loop because
This is my extension code: class HyperlinkedRelatedFieldFix(OpenApiSerializerFieldExtension):
target_class = "rest_framework.relations.HyperlinkedRelatedField"
def map_serializer_field(self, auto_schema, direction):
base = auto_schema._map_serializer_field(self.target, direction)
base["format"] = "uri"
base["example"] = "https://{}/api/management/v2/<objecttype>/<objectid>".format(
settings.DEFAULT_DOMAIN
)
return base I'll try to find a workaround, but for future readers here, don't just copy-paste that solution. |
Workaround: class HyperlinkedRelatedFieldFix(OpenApiSerializerFieldExtension):
target_class = "rest_framework.relations.HyperlinkedRelatedField"
def map_serializer_field(self, auto_schema, direction):
# temporarily "disable" this extension to prevent running it again when calling the AutoSchema method
HyperlinkedRelatedFieldFix.target_class = None
base = auto_schema._map_serializer_field(self.target, direction)
# reenable this extension
HyperlinkedRelatedFieldFix.target_class = "rest_framework.relations.HyperlinkedRelatedField"
base["format"] = "uri"
base["example"] = "https://{}/api/management/v2/<objecttype>/<objectid>".format(
settings.DEFAULT_DOMAIN
)
return base |
oh right. sry about that. i didn't think of that. probably the reason why i didn't do that myself anywhere. i'll think about something better. |
Here's a cleaner subclass that can be extended instead of class SerializerFieldExtensionWithOverride(OpenApiSerializerFieldExtension):
def get_default_output(self, auto_schema, direction):
child_cls = type(self)
backup_target_class = child_cls.target_class
child_cls.target_class = None
base_schema = auto_schema._map_serializer_field(self.target, direction)
child_cls.target_class = backup_target_class
return base_schema Usage: class NullBooleanFieldFix(SerializerFieldExtensionWithOverride):
target_class = "rest_framework.fields.NullBooleanField"
def map_serializer_field(self, auto_schema, direction):
defaults = self.get_default_output(auto_schema, direction)
defaults["nullable"] = True
return defaults Are you interested in a PR to add the |
hey @foucdeg, that certainly works and is a nifty idea, although not the cleanest solution imho. it's probably better to run the method but indicate that extensions should not be entered. maybe we should add a parameter to auto_schema._map_serializer_field(self.target, direction, bypass_extensions=True) that way we don't have to temporarily hack the extension. that do you think? |
I'd mix both solutions:
The new method has the advantage of being more explicit / self-documented for users trying to figure out how to do what I needed to do. What do you think @tfranzel ? |
so i took your comment into consideration, but decided against having both. i only implemented the reason is that in nearly half of the cases this will not work anyway due warnings in the regular codepath. also |
In the example provided for OpenApiSerializerFieldExtension, the override simply returns a basic type.
The customization we would like to do is extend from the default output for the field, keeping
description
which is derived from the Django model field'shelp_text
but adding anexample
.It would look like this:
Sorry for asking a lot of questions in a short time, but your quick replies have encouraged me to ask more questions :)
The text was updated successfully, but these errors were encountered: