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

Refactor filterforms in list Views #318

Open
mina-atef-00 opened this issue Jun 19, 2022 · 5 comments
Open

Refactor filterforms in list Views #318

mina-atef-00 opened this issue Jun 19, 2022 · 5 comments
Assignees
Labels
not a priority refactoring REST issues related to the Django REST Framework

Comments

@mina-atef-00
Copy link
Collaborator

Type of Issue: Code refactor

Steps to Reproduce:

  • Visit a list view page.

Expected Behavior:

  • Fully serialized response that works with DRF browsable API.

Current Behavior:

Code Snippets:

  1. HarvestViewset.list() context (without serializer output):
{'filter': {'form': <HarvestFilterForm bound=True, valid=Unknown, fields=(status;pick_leader;trees;property__neighborhood;season)>},
 'new': {'title': 'New Harvest', 'url': '/harvest/create/'}}

Related URLs:

https://localhost:8000/harvest/
And the rest of the list views.

@mina-atef-00 mina-atef-00 added refactoring REST issues related to the Django REST Framework labels Jun 19, 2022
@mina-atef-00 mina-atef-00 self-assigned this Jun 19, 2022
@mina-atef-00
Copy link
Collaborator Author

mina-atef-00 commented Jun 19, 2022

Tasks:

  • Add 'new' to the response.data of the serializers.
  • refactor get_filter_context()

@mina-atef-00 mina-atef-00 changed the title Refactor list functions in Viewsets Refactor filterforms in list Views Jun 20, 2022
@mina-atef-00
Copy link
Collaborator Author

hi @2ynn,
I'm running into a problem with the listviews context:
in the CommunityViewset for example:

class CommunityViewset(LoginRequiredMixin, viewsets.ModelViewSet):

    ...

    def list(self, request, *args, **kwargs):
        response = super(CommunityViewset, self).list(request, *args, **kwargs)
        if request.accepted_renderer.format == 'json':
            return response
        # default request format is html:
        return Response(
            {
                'data': response.data,
                'filter': get_filter_context(self),
                ######################!!!!!!!!!!!!!
                'new': { 
                    'url': reverse_lazy('person-create'),
                    'title': _("New Person")
                    }
            }
        )

To enable the html filtering in DRF browsable api, I have to return only the serializer output:
image

So when it comes to 'new' (data provided for the "New Person" btn) I can't pass it to the serialzer.
image

If I for example add a new serializermethodfield returning a "new" dictionary-because this is a list view-it will add the 'new' data to every instance in the output:
image
Do you know what can be done to solve this?

@2ynn
Copy link
Collaborator

2ynn commented Jun 21, 2022

@mina-andajos have you looked into the to_representation method to add additional context to serializer only once (not once per object)?
https://www.django-rest-framework.org/api-guide/relations/#custom-relational-fields

@2ynn
Copy link
Collaborator

2ynn commented Jun 21, 2022

for example you could do something like this:

class MySerializer(serializers.ModelSerializer):
[...]
    def to_representation(self, obj):
        ord_dic = super().to_representation(obj)
        ord_dic['new'] = "new_data"
        return ord_dic

And the 'new' field would be added only once, not for all objects

This is nice when you have nested serializers (with many=True) but it might not be what you are looking for in the case of a list view. Instead you can pass additional context to the Viewset using get_serializer_context:

  def get_serializer_context(self):
        context = super().get_serializer_context()
        context['new'] = "new_data"
        return context

https://stackoverflow.com/questions/39202380/django-rest-framework-how-to-add-context-to-a-viewset

@mina-atef-00
Copy link
Collaborator Author

mina-atef-00 commented Jun 22, 2022

hi @2ynn ,

1- I tried the to_representation() before, it does the same thing as adding a new method field, it adds 'new' to every instance in the serializer output:

[
    {
        "id": 3,
        "person": {
            "actor_id": 4,
            "name": "Mina Andajos",
            ...
        "new": {
            "url": "/person/create/",
            "title": "New Person"
        }
    },
    {
        "id": 2,
        "person": {
        #!!!!! another new below

2- I also found that the JSON list response of the serializer doesn't work with the HTML templates as they expect a dict.
image

3- I followed the stackoverflow link you provided as well but I'm still facing the same error above.


I'm thinking of this method to fix these problems:

  • I could make the list functions check for the template rendering engine (whether we're using the browsable api or the html templates)
  • And then switch to the default serializer list output when we're using the browsable api. And just the default context when using the templates.
  • Therefore the filter button will work on the browsable api. And the html template rendering will work normally.

What do you think?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
not a priority refactoring REST issues related to the Django REST Framework
Projects
None yet
Development

No branches or pull requests

2 participants