mjumbewu / django-rest-framework-csv

CSV Tools for Django REST Framework

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Possibility to add headers ordering in the render method

moumoutte opened this issue · comments

Actually, it's pretty difficult to maintain a renderer with ordering columns when the columns are generated dynamicaly. It will be nice to have a way to override the headers attributes on the single instance at the render time.

def render(self, headers=None, *args, **kwargs):
    if headers:
        self.headers = headers
     # Do the rendering

With this patch , we can have two way to fill up the headers values, it will be very helpful.

If you want I can write a patch

Please use OrderedDict for flattened lists and dicts, it keeps the order given by DRF.

An option in order to provide the headers' order will be gratefully accepted too!

👍

I also could really use ordering based on the serializer field definition.

👍 for this feature.

I'll try a patch as soon as I have some time. Before the week-end I guess

👍 was this ever implemented @moumoutte? would be really useful :)

Just add the order kwargs in render method, does it looks good to you ?

Thanks @moumoutte for the pull request! It looks good, but I'm wondering whether it would be more useful if the order argument were an attribute on the class instead. I imagine myself using something like this in the following way:

class MyUserRenderer (CSVRenderer):
    order = ['first', 'last', 'email']

@api_view(['GET'])
@renderer_classes((MyUserRenderer,))
def my_view(request):
    users = User.objects.filter(active=True)
    content = [
        {'first': user.first_name, 'last': user.last_name, 'email': user.email}
        for user in users]
    return Response(content)

As a backup, it could be passed in with the renderer_context:

class MyView (APIView):
    renderer_classes = [CSVRenderer]

    def get_renderer_context(self):
        context = super().get_renderer_context()
        context['order'] = (
            self.request.GET['fields'].split(',') 
            if 'fields' in self.request.GET else None)
        return context

    ...
# Then I can specify field order as part of my request.
curl http://localhost:8000/api/my_view?fields=first,last,email

Either way, I feel like I don't call render directly from my code, so the keyword argument would be of limited use to me. Am I an outlier in that regard?

100% agree with mjumbewu about how I would use this.

Actually, somehow I missed this, but it seems that what I described above (ordering with a class attribute) was introduced by @robguttman in pull request #3, commit 93236a0 (the attribute is called headers). Should be available since release 1.2.0

I just released 1.4.0 which allows sorting fields using the header attribute on the CSVRenderer class, or using the "header" key in the renderer_context. I'm going to close this issue. Thanks @moumoutte for kicking off the thread!

It will also be good to override headers with a dict providing custom titles, is it possible?

@debnet This is actually possible as of version 1.4.1 (released today! see pull request #39)