dynamically modifying fields in DRF3

218 views
Skip to first unread message

张留成

unread,
Dec 24, 2014, 9:56:34 PM12/24/14
to django-res...@googlegroups.com
Hi All:


I'm a new one to the  DRF3, i want to know how to dynamically modifying fields.


 that's mean i can't use the ModelViewSet ? 

the fields is from the request params ,is there any way get the request params like this (red color):

class DynamicFieldsModelSerializer(serializers.ModelSerializer):
    """
    A ModelSerializer that takes an additional `fields` argument that
    controls which fields should be displayed.
    """

    def __init__(self, *args, **kwargs):
        # Instantiate the superclass normally
        super(DynamicFieldsModelSerializer, self).__init__(*args, **kwargs)

        fields = self.request.get('fields')
        no_fields = self.request.get('nofields')

        if fields is not None:
            # Drop any fields that are not specified in the `fields` argument.
            allowed = set(fields[1:-1].split(','))
            existing = set(self.fields.keys())
            for field_name in existing - allowed:
                self.fields.pop(field_name)

        if no_fields is not None:
            for field_name in set(no_fields[1:-1].split(',')):
                self.fields.pop(field_name)


Zoltan Szalai

unread,
Dec 25, 2014, 9:29:01 AM12/25/14
to django-res...@googlegroups.com
you should normally be able to access the request object in the serializer via the context attr (if the serializer got instantiated from a GenericAPIView subclass):
request = self.context.get('request')
and then:
request.query_params.get('fields')
request.query_params.get('nofields')
etc.

but if you happen to use the default pagination then it's not working. at least in 3.0.2. which is a bug I guess, but I don't have time to dig deeper right now.


On 2014.12.25. 3:56, 张留成 wrote:
Hi All:


I'm a new one to the  DRF3, i want to know how to dynamically modifying fields.

i follow the link: http://www.django-rest-framework.org/api-guide/serializers /#dynamically-modifying-fields . 

 that's mean i can't use the ModelViewSet ? 

the fields is from the request params ,is there any way get the request params like this (red color):

class DynamicFieldsModelSerializer(serializers.ModelSerializer):
    """
    A ModelSerializer that takes an additional `fields` argument that
    controls which fields should be displayed.
    """

    def __init__(self, *args, **kwargs):
        # Instantiate the superclass normally
        super(DynamicFieldsModelSerializer, self).__init__(*args, **kwargs)

        fields = self.request.get('fields')
        no_fields = self.request.get('nofields')

        if fields is not None:
            # Drop any fields that are not specified in the `fields` argument.
            allowed = set(fields[1:-1].split(','))
            existing = set(self.fields.keys())
            for field_name in existing - allowed:
                self.fields.pop(field_name)

        if no_fields is not None:
            for field_name in set(no_fields[1:-1].split(',')):
                self.fields.pop(field_name)


--
You received this message because you are subscribed to the Google Groups "Django REST framework" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-rest-fram...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Tom Christie

unread,
Dec 25, 2014, 10:06:58 AM12/25/14
to django-res...@googlegroups.com
> but if you happen to use the default pagination then it's not working. at least in 3.0.2. which is a bug I guess

I'm not sure what's being referred to there - you might consider raising an issue if you think there's a problem.

Zoltan Szalai

unread,
Dec 25, 2014, 11:03:17 AM12/25/14
to django-res...@googlegroups.com
hi Tom,

https://github.com/tomchristie/django-rest-framework/issues/2355
hope this helps to reproduce it.

bests
Zoli

andyz

unread,
Dec 25, 2014, 8:08:34 PM12/25/14
to django-res...@googlegroups.com
Thanks for u reply .. i will try as you say 


在 2014年12月25日,下午10:28,Zoltan Szalai <defau...@gmail.com> 写道:

pagination

andyz

unread,
Dec 25, 2014, 10:10:16 PM12/25/14
to django-res...@googlegroups.com
Hi Zoli:

I'm try as you said . it only works at api which without pagination. 

Do you have found the way work with paination? Could you help to offer a simple ? 

thanks a lot  

--
You received this message because you are subscribed to a topic in the Google Groups "Django REST framework" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/django-rest-framework/m4wB5VxfcjQ/unsubscribe.
To unsubscribe from this group and all its topics, send an email to django-rest-fram...@googlegroups.com.

andyz

unread,
Dec 26, 2014, 5:09:45 AM12/26/14
to django-res...@googlegroups.com
Hi:

The code seems like that .don't init with the args at BasePaginationSerializer. 

It works fine when i change the code as bellow.



i have created a pull request for this 

Renzo Canepa

unread,
Dec 27, 2014, 11:01:11 PM12/27/14
to django-res...@googlegroups.com
Hi Zolta,

Did you accomplish what you wanted?. I think I am facing the same situation. I need to dynamically set the fields using data from request parameters. This is my code:

class DynamicFieldsModelSerializer(serializers.ModelSerializer):
   
"""
    A ModelSerializer that takes an additional `fields` argument that
    controls which fields should be displayed.
    """



   
def __init__(self, *args, **kwargs):

       
super(DynamicFieldsModelSerializer, self).__init__(*args, **kwargs)

        request
= self.context.get('request')

       
print request
        fields
= request.query_params.get('fields')

       
if fields is not None:
           
# Drop any fields that are not specified in the `fields` argument.

            allowed
= set(fields)

            existing
= set(self.fields.keys())
           
for field_name in existing - allowed:
               
self.fields.pop(field_name)




The print request statement is printing the next lines (for every time I make a request to the view):
None
None
<rest_framework.request.Request object at 0x7f3ac1c96d50>
<rest_framework.request.Request object at 0x7f3ac1635190>
<rest_framework.request.Request object at 0x7f3ac1635fd0>

And I am getting this error:

File "/home/rcanepa/Development/simpleclerk/simpleclerk/utils.py", line 22, in __init__
    fields = request.query_params.get('fields')
AttributeError: 'NoneType' object has no attribute 'query_params'

How did you solve it?

To unsubscribe from this group and stop receiving emails from it, send an email to django-rest-framework+unsub...@googlegroups.com.

Renzo Canepa

unread,
Dec 27, 2014, 11:28:47 PM12/27/14
to django-res...@googlegroups.com
I found a solution for my need. I will leave it here in case that anyone need to solve the same problem.

You can pass the fields in the URL in this way: http://localhost:8000/api/persons?fields=id,first_name,organization

class DynamicFieldsModelSerializer(serializers.ModelSerializer):
   
"""

    A ModelSerializer that takes an additional `fields` argument that
    controls which fields should be displayed. The argument comes
    from the request object.

    """



   
def __init__(self, *args, **kwargs):
       
super(DynamicFieldsModelSerializer, self).__init__(*args, **kwargs)

        request
= self.context.get('request', None)
       
if request and request.method == 'GET':
            fields
= request.query_params.get('fields', None)

           
if fields is not None:

                allowed
= set(fields.split(','))

                existing
= set(self.fields.keys())
               
for field_name in existing - allowed:
                   
self.fields.pop(field_name)

andyz

unread,
Dec 28, 2014, 1:31:20 AM12/28/14
to django-res...@googlegroups.com
Hi Renzo:

Seems like that , the solution you privoid is not work! the request is still None!

--
You received this message because you are subscribed to a topic in the Google Groups "Django REST framework" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/django-rest-framework/m4wB5VxfcjQ/unsubscribe.
To unsubscribe from this group and all its topics, send an email to django-rest-fram...@googlegroups.com.

Renzo Canepa

unread,
Dec 28, 2014, 10:48:23 AM12/28/14
to django-res...@googlegroups.com
Hi,

Are you sure?. This line should do the trick:

if request and request.method == 'GET':

I successfully used it on one of my API's REST point.
To unsubscribe from this group and stop receiving emails from it, send an email to django-rest-framework+unsubscri...@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

--
You received this message because you are subscribed to a topic in the Google Groups "Django REST framework" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/django-rest-framework/m4wB5VxfcjQ/unsubscribe.
To unsubscribe from this group and all its topics, send an email to django-rest-framework+unsub...@googlegroups.com.

andyz

unread,
Dec 28, 2014, 11:12:46 AM12/28/14
to django-res...@googlegroups.com
hmm... 

for example : 

GET /test/
{
    "id":1,
    "name":"test"
}

GET /test/?fields=id

{
    "id":1
}

work like this ?

Across the Great Firewall, you can reach every corner in the world.

To unsubscribe from this group and all its topics, send an email to django-rest-fram...@googlegroups.com.

Renzo Canepa

unread,
Dec 28, 2014, 12:42:52 PM12/28/14
to django-res...@googlegroups.com
Yeah, that is what I was looking for.
To unsubscribe from this group and all its topics, send an email to django-rest-framework+unsubscri...@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

Tom Christie

unread,
Jan 5, 2015, 11:40:36 AM1/5/15
to django-res...@googlegroups.com
> if you happen to use the default pagination then it's not working. at least in 3.0.2. which is a bug I guess

Reply all
Reply to author
Forward
0 new messages