Skip to content
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

Support for Polymorphic Lists #382

Closed
avere001 opened this issue May 12, 2021 · 8 comments
Closed

Support for Polymorphic Lists #382

avere001 opened this issue May 12, 2021 · 8 comments
Labels
enhancement New feature or request fix confirmation pending issue has been fixed and confirmation from issue reporter is pending

Comments

@avere001
Copy link

I have tried this a few ways, but there seems to be no way to get polymorphic lists. For example, I can't find a way to document the content property of something like this:

{
  "type": "page",
  "content": [
    {
      "type": "article",
      "title": "...",
      "body": "..."
    },
    {
      "type": "image",
      "url": "...",
      "alt_text": "..."
    }
  ]
}

For me, the natural thing was to annotate the field with PolymorphicProxySerialzier(many=True, ...) but that doesn't work.

Is there any way to do this without using django-polymorphic / django-rest-polymorphic?

@tfranzel
Copy link
Owner

hi!

Is there any way to do this without using django-polymorphic / django-rest-polymorphic?

that is exactly the purpose of PolymorphicProxySerializer. it simulates what those libraries would do without having to use them. as a matter of fact you wouldn't use PolymorphicProxySerializer with those libraries, as instances of PolymorphicSerializer would get picked up automatically.

regarding your question. if the field is readOnly this is the easiest solution:

def test_polymorphic_serializer_as_method_field_via_extend_schema_field(no_warnings):

for read/write, you have to subclass the field and annotate that class. a pass will suffice as you just need something to attach the annotation to.

def test_polymorphic_serializer_as_field_via_extend_schema_field(no_warnings):

sidenote:
maybe we could extend extend_schema_serializer to additionally allow field overrides. that would eliminate that awkward annotation exercise. definitely something to look into.

@avere001
Copy link
Author

Hi @tfranzel, thank you for the response.

The example you gave me only works when a single object is being returned, e.g.:

@extend_schema_field(
    PolymorphicProxySerializer(
        component_name='MetaPerson',
        serializers=[LegalPersonSerializer, NaturalPersonSerializer],
        resource_type_field_name='type',
    )
)
def get_field(self, request):
    return LegalPersonSerializer(...).data. # or NaturalPersonSerializer(...).data

What I want is the schema for a list of objects of varying types being returned such as below:

@extend_schema_field(
    PolymorphicProxySerializer(
        component_name='MetaPerson',
        serializers=[LegalPersonSerializer, NaturalPersonSerializer],
        resource_type_field_name='type',
        many=True,  # <--- This doesn't work
    )
)
def get_field(self, request):
    return [
        LegalPersonSerializer(...).data,
        NaturalPersonSerializer(...).data,
        ...
    ]

@greenled
Copy link

greenled commented May 14, 2021

I'm looking for a solution to this problem too. For me, a PolymorphicProxySerialzier(many=True, ...) field, as mentioned by @avere001, would be the most natural API.

@tfranzel
Copy link
Owner

@avere001 now i get where you are coming from. this is indeed a missing feature.

now that i think of it there are ways to get PolymorphicProxySerialzier into "many mode" (via annotation of a viewsets's list) but there is currently no way to do it explicitly. certainly an unnecessary limitation.

good catch! i'll figure something out.

@tfranzel tfranzel added the enhancement New feature or request label May 14, 2021
@avere001
Copy link
Author

Cool, thank you @tfranzel!

tfranzel added a commit that referenced this issue May 20, 2021
PolymorphicProxySerializer is now derived from Serializer
with certain safeguards as mocking behaviour became
increasingly complicated. Now its the real thing.
@tfranzel tfranzel added the fix confirmation pending issue has been fixed and confirmation from issue reporter is pending label May 20, 2021
@tfranzel
Copy link
Owner

please test if that fix works for you guys. cheers!

@avere001
Copy link
Author

Just tested it and it is exactly what I was looking for. I appreciate your time on this, @tfranzel!

@unrealsolver
Copy link

@avere001 , do you have a full example for the usage? I am trying to do something very similar. Spectacular part is clear, but DRF is not.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request fix confirmation pending issue has been fixed and confirmation from issue reporter is pending
Projects
None yet
Development

No branches or pull requests

4 participants