Django Rest Framework: getting lists from query_pa

2019-07-10 00:04发布

问题:

We use serializers to to validate the data coming into our non-model based service methods. This works great for POSTs as JSON of course but also for GETs generally if the content in the query_params is not complex (not lists or nested). However if I have something like this:

class RequestSerializer(Serializer):
   objects = ListField(child=PrimaryKeyRelatedField(queryset=Foo.objects.all()), allow_empty=False)
   choice = ChoiceField(choices=my_choices)

and on the client I just use a GET like so:

$.ajax({
   type: "GET",
   url: '...',
   data={
      "objects":[1,2,3],
      "choice":"mychoice"
      ...

this works if I use POST instead of GET and set the contentType to "application/json" but this is not condoned by the HTTP spec. It would be nice to be able to handle the simple list use case without doing something like:

request_serializer = RequestSerializer(data={"objects" :request.query_params.getlist("objects[]")})

Is there some obvious serializer trick I am missing that tells the serializer how to fetch a list(objects=x&objects=y&objects=z) without manually calling request.getlist? What is everyone else doing for this, it seems like a common use case?

EDIT: I did find this post earlier but the accepted answer is using request.getlist which is not what I want.

回答1:

The answer is to use the jQuery ajaxSettings

$.ajaxSettings.traditional = true;

if you are using jQuery in your templates and from what I am reading it should be probably used for the entire project using Django because it does not seem to suffer from the same limitations as other languages.

As of jQuery 1.4, the $.param() method serializes deep objects recursively to accommodate modern scripting languages and frameworks such as PHP and Ruby on Rails.

Leaving this false causes the variable to come through as "objects[]" and the code that would handle HTML lists in ListField never gets invoked because the param has been replaced.



回答2:

Not exactly sure what your question is but seems you should use the many argument for the field:

class RequestSerializer(Serializer):
    objects = PrimaryKeyRelatedField(queryset=Foo.objects.all(), allow_empty=False, many=True)
    choice = ChoiceField(choices=my_choices)