rsinger86/drf-flex-fields

Bug in serializer when passing params

Closed this issue · 2 comments

Hi!
Thanks for the great library! I faced an issue with multiple nested fields expansion and was able to track it down to the following lines:

if name in nested_expand:
settings["expand"] = nested_expand[name]
if name in nested_fields:
settings["fields"] = nested_fields[name]
if name in nested_omit:
settings["omit"] = nested_omit[name]
if type(serializer_class) == str:
serializer_class = self._get_serializer_class_from_lazy_string(
serializer_class
)
return serializer_class(**settings)

TypeError: __init__() got an unexpected keyword argument 'expand'

Since I am using custom REST_FLEX_FIELDS params, this is throwing an error because the serializer expected parameters with different names since you only pop off the expected custom params

def __init__(self, *args, **kwargs):
expand = list(kwargs.pop(EXPAND_PARAM, []))
fields = list(kwargs.pop(FIELDS_PARAM, []))
omit = list(kwargs.pop(OMIT_PARAM, []))
super(FlexFieldsSerializerMixin, self).__init__(*args, **kwargs)

I believe all thats needed to fix this is to edit this section to utilize the custom params instead when passing

There is also another bug here that is possible when you are passing the settings here:

if type(serializer_class) == str:
serializer_class = self._get_serializer_class_from_lazy_string(
serializer_class
)
return serializer_class(**settings)

The serializer_class might not actually be a subclass of FlexFieldsSerializerMixin in which case passing the kwargs will result in a TypeError (again) since the __init__ method of ModelSerializer is explicitly defined (it has no extra kwargs)

I believe a check is needed here first to check if the serializer_class is an actual subclass of FlexFieldsSerializerMixin i.e:

 if name in nested_expand: 
    settings["expand"] = nested_expand[name] 
 
if name in nested_fields: 
    settings["fields"] = nested_fields[name] 
 
if name in nested_omit: 
    settings["omit"] = nested_omit[name] 
 
if type(serializer_class) == str: 
    serializer_class = self._get_serializer_class_from_lazy_string( 
        serializer_class 
    ) 
 
if issubclass(serializer_class, FlexFieldsSerializerMixin): 
    return serializer_class(**settings)
return serializer_class() 

Ah, nice catches. I'll get these in a new release soon.