AltSchool / dynamic-rest

Dynamic extensions for Django REST Framework
MIT License
831 stars 109 forks source link

Swagger generation while using dynamic-rest is it possible? Issue with @property field on model #306

Open allen-munsch opened 4 years ago

allen-munsch commented 4 years ago

I'm trying to determine how feasible it is to run https://github.com/axnsan12/drf-yasg with the addition of dynamic-rest.

has anyone here successfully generated swagger docs, types with dynamic-rest? any suggestions? does it work with the DRF swagger builtins?

I'm getting hung up on running the drf-yasg generate command, while it tries to introspect a django @property field on a model:

  File "/home/jmunsch/PycharmProjects/pm/venv_ok/lib/python3.6/site-packages/drf_yasg/openapi.py", line 690, in setdefault
    ret = maker()
  File "/home/jmunsch/PycharmProjects/pm/venv_ok/lib/python3.6/site-packages/drf_yasg/inspectors/field.py", line 102, in make_schema_definition
    for property_name, child in serializer.fields.items():
  File "/home/jmunsch/PycharmProjects/pm/venv_ok/lib/python3.6/site-packages/django/utils/functional.py", line 80, in __get__
    res = instance.__dict__[self.name] = self.func(instance)
  File "/home/jmunsch/PycharmProjects/pm/venv_ok/lib/python3.6/site-packages/rest_framework/serializers.py", line 361, in fields
    fields[key] = value
  File "/home/jmunsch/PycharmProjects/pm/venv_ok/lib/python3.6/site-packages/rest_framework/utils/serializer_helpers.py", line 145, in __setitem__
    field.bind(field_name=key, parent=self.serializer)
  File "/home/jmunsch/PycharmProjects/pm/venv_ok/lib/python3.6/site-packages/dynamic_rest/fields/fields.py", line 135, in bind
    remote = is_field_remote(parent_model, self.source)
  File "/home/jmunsch/PycharmProjects/pm/venv_ok/lib/python3.6/site-packages/dynamic_rest/meta.py", line 136, in is_field_remote
    model_field = get_model_field(model, field_name)
  File "/home/jmunsch/PycharmProjects/pm/venv_ok/lib/python3.6/site-packages/dynamic_rest/meta.py", line 84, in get_model_field
    raise AttributeError(
AttributeError: display_address is not a valid field for <class 'property.models.Unit'>

I am able to successfully get a response back with curl while the API is running using dynamic-rest

So the issue isn't with the library not working, but perhaps in how the _property_name is being returned as per the expectations of drf, and drf-yasg swagger generation in meta.py?

The field itself I got working by defining it as follows:

class UnitSerializer(DynamicModelSerializer):
    ... some other fields ...
    display_address = DynamicMethodField()

    def get_display_address(self, obj):
        da = obj.display_address
        if isinstance(da, Address):
            return BaseAddressSerializer(da).data
        else:
            assert isinstance(da, Property)
            return BasePropertySerializer(da).data