drf-flex-fields icon indicating copy to clipboard operation
drf-flex-fields copied to clipboard

How to use it with django-rest-framework-recursive RecursiveField?

Open noodlebreak opened this issue 7 years ago • 7 comments

Hi!

Basically this is what I'm talking about: https://github.com/dbrgn/drf-dynamic-fields/issues/25

Will it even work with that TPA's RecursiveField implementation? If not, can you point me in the right direction with regards to what to change in drf-flex-fields' code?

Thanks.

noodlebreak avatar Jul 18 '18 13:07 noodlebreak

No one guys? Basically I want to be able to carry forward the functionality into all the n-level recursed fields.

noodlebreak avatar Jul 20 '18 11:07 noodlebreak

Hi there, apologies for the delay. Unfortunately, I haven't had a chance to look into this yet. I'm on vacation next week, but should be able to look at this the following week.

rsinger86 avatar Jul 20 '18 18:07 rsinger86

@rsinger86 if you could just point me in the correct direction, like where in the code to try out what, that would be enough for me as well.

noodlebreak avatar Jul 21 '18 14:07 noodlebreak

I have same the question. Please when you come back from vacations, let us know

german970814 avatar Jul 31 '18 22:07 german970814

hi @noodlebreak, I'm not sure from the linked example how you'd like the behavior tweaked.

When you request http://api.mlocal.com/api/v1/categories/?fields=id,value,children, do you want the serialized items of the children array to only have id and value fields?

If further clarification is necessary, maybe you could provide some more details on expected input (url w/ params) and output (serialized response)?

rsinger86 avatar Aug 01 '18 00:08 rsinger86

@rsinger86 you can check the url and the response in my first post in the linked issue in drf-dynamic-field's repo.

But the response I need is to be like this:

{
  "count": 20,
  "next": null,
  "previous": null,
  "results": [
    {
      "id": "5914220d-c455-45ff-a135-e9ac7f307dae",
      "value": "Fruits & Vegetables",
      "children": [
        {
          "id": "7426afb3-b2b6-4f74-8a25-6e5e5865fb4f",
          "value": "Fresh Vegetables",
          "image": null,
          "children": [],
        }
      ],
      "image": "http://api.mlocal.com/categories/35629/fruits-vegetables-41698-1523944087.png"
    }
  ]
}

Basically, all the nested objects also to respect the fields filter and have only the fields specified.

noodlebreak avatar Aug 01 '18 06:08 noodlebreak

@noodlebreak , @rsinger86 , I have solve with this code, I've overwritten _make_expanded_field_serializer method, and added new option called depth:

def _make_expanded_field_serializer(self, name, nested_expands, nested_includes):
        """
        Returns an instance of the dynamically created nested serializer. 
        """
        field_options = self.expandable_fields[name]
        serializer_class = field_options[0]
        serializer_settings = copy.deepcopy(field_options[1])
        depth = (self.depth - 1) if self.depth is not None else None

        if depth:
            serializer_settings['depth'] = depth

        if depth == 0:
            serializer_settings['expand'] = []

        if name in nested_expands:
            if 'expand' in serializer_settings:
                serializer_settings['expand'] += nested_expands[name]
            else:
                serializer_settings['expand'] = nested_expands[name]

        if name in nested_includes:
            serializer_settings['fields'] = nested_includes[name]

        if serializer_settings.get('source') == name:
            del serializer_settings['source']
            
        if type(serializer_class) == str:
            serializer_class = self._import_serializer_class(serializer_class) 
        
        return serializer_class(**serializer_settings)

I define serializers like this:

class ConjuntoSerializer(FlexFieldsModelSerializer):
    class Meta:
        model = models.Conjunto
        fields = (
            'id', 'parent', 'descripcion',
            'nombre', 'identificador', 'repetible',
            'children_set',
        )

    expandable_fields = {
        'parent': ('main.ConjuntoSerializer', {'source': 'parent'}),
        'children_set': ('main.ConjuntoSerializer', {
            'source': 'children_set', 'many': True, 'expand': 'children_set'
        })
    }

And I call from this way ConjuntoSerializer(Conjunto.objects.last(), expand=['~all'], depth=1).data

german970814 avatar Aug 01 '18 15:08 german970814