Open Amoki opened 5 years ago
I think this is an inherent problem with the current API design. What you did looks like the only way to achieve it...
Maybe a 2.0 release would make this cleaner, somehow.
This is a snippet I wrote for examples, which only overrides the attribute if provided in the swagger_schema_fields property as a example key:
class Meta:
model = Model
fields = ('a', 'b', 'c')
swagger_schema_fields = {
'example': {
'a':'foo'
}
def add_manual_fields(self, serializer_or_field, schema):
meta = getattr(serializer_or_field, 'Meta', None)
swagger_schema_fields = getattr(meta, 'swagger_schema_fields', {})
if swagger_schema_fields:
for attr, val in swagger_schema_fields.items():
if attr == 'example':
for key in val.keys():
if key in schema['properties']:
schema['properties'][key]['example'] = val[key]
else:
setattr(schema, attr, val)
This would show 'a' as being 'foo', but still leave b and c as their default.
Hi guys,
Is there any open change pending to implement recursive merge for add_manual_fields I think it would be very useful as it is the only way to manipulate properties schema through serializer and not creating custom schema from scratch. Maybe some kwarg indicating recursive behavior would be a good option. If I would write a patch could it be accepted ? I mean recursive behavior is sth You would like to implement or You plan to make it easier to change FieldInspector behavior globally ?
Best, Igor
@Amoki I have override the add_manual_fields for FieldInspector only and it affected other Inspectors too.
def add_manual_fields(self, serializer_or_field, schema):
meta = getattr(serializer_or_field, 'Meta', None)
swagger_schema_fields = getattr(meta, 'swagger_schema_fields', {})
if swagger_schema_fields:
for attr, val in swagger_schema_fields.items():
if isinstance(val, dict) and isinstance(getattr(schema, attr, None), dict):
to_update = dict(list(getattr(schema, attr).items()) + list(val.items()))
setattr(schema, attr, to_update)
else:
setattr(schema, attr, val)
from drf_yasg.inspectors.field import FieldInspector, SerializerInspector
FieldInspector.add_manual_fields = add_manual_fields
# SerializerInspector.add_manual_fields = add_manual_fields
and serializer:
class TestResponseSerializer(serializers.Serializer):
x = serializers.IntegerField()
class Meta:
swagger_schema_fields = {
'properties': {
'x': {'type': 'integer', 'format': None, 'x-attribute': 'example'}
}
}
Btw one additional question, if we are considering django/django-rest application, where it would be best to place add_manual_fields overriding. Maybe sb already did it ? I would appreciate some advice.
Ok at the end I have decided to create a separate python file with method overriding logic and I am importing it in django settings.py.
Btw one additional question, if we are considering django/django-rest application, where it would be best to place add_manual_fields overriding. Maybe sb already did it ? I would appreciate some advice.
I also stumbled upon the issue of manually annotationg fields and could think of a more or less practicable place to make this override efficent. My suggestion would be adding an optional inspector_classes
parameter to the get_schema_view()
function and passing it trough to the point (sorry, didn't dig deep enough to be more specific) where the Serializers/Fields get actually inspected.
That way one could override the add_manual_fields()
method by simply subclassing the Inspectorclass of desire and pass it to the schema creation.
How do you think about that? (I'd be willing to dig deeper an eventually provide a PR ;) )
Looking further into this, isn't your proposal just an extension to the FieldInspector class's add_manual_field()
method ?
I'd like to override the
swagger_schema_fields
behavior: Instead of totally replacing schema fields with provided fields, I'd like to override just some properties (a deep merge).Is there a way to subclass
FieldInspector.add_manual_fields
method without having to subclass/override all inspectors?I share here my merge method even it is not tested and designed only to fit my needs. It may interest someone!