0

I'm trying to make an API with Django rest framework but I'm struggling to modify the JSON response as I want. If you need anything else, just ask, Thanks for your help!

models.py :

class Feature(models.Model):
    name = models.CharField(max_length=255, unique=True, null=True)

    def __str__(self):
        return "{}" .format(self.name)

    def save(self, *args, **kwargs):
        super(Feature, self).save(*args, **kwargs)

class Opponent(models.Model):
    name = models.CharField(max_length=255, unique=True, null=True)
    features = models.ManyToManyField(Feature, blank=True, null=True)

    def __str__(self):
        return "{}" .format(self.name)

    def save(self, *args, **kwargs):
        super(Opponent, self).save(*args, **kwargs)

serializers.py :

class FeatureSerializer(serializers.ModelSerializer):
    opponents = serializers.RelatedField(many=True)

    class Meta:
        model = Feature

views.py :

@csrf_exempt
@jsonify
def get_opponents(request):
    if request.method == 'OPTIONS':
        return HttpResponse()

opponents = list(Opponent.objects.all().values('id', 'features'))
return opponents

def jsonify(f):
    @wraps(f)
    def wrapper(*args, **kwds):
        response = f(*args, **kwds)
        if isinstance(response, HttpResponse):
            return response
        return HttpResponse(simplejson.dumps(response, ignore_nan=True))

    return wrapper

JSON response :

[
    {
        "id": 1,
        "features__name": "feature1"
    },
    {
        "id": 1,
        "features__name": "feature2"
    }
]

What I want :

[
    {
        "id": 1,
        "features": ["feature1", "feature2"]
    }
]
2
  • What is @jsonify here? You don't seem to be using Django REST Framework at all here - you appear to be bypassing it, and using whatever that jsonify decorator is instead. Commented Jan 26, 2018 at 9:22
  • @DanielRoseman I've added @jsonify Commented Jan 26, 2018 at 9:31

1 Answer 1

1

As I said in the comments, you're not using Django REST Framework at all here - by using a standard view and your jsonify decorator, you've bypassed everything DRF does for you, including the serializer.

So first of all you should stop doing that, and use a proper DRF view instead. That gives you the ability to create a custom serializer to give you the structure you need.

Since it is actually Opponents, with their related Features, that you want to serialize, you should create an OpponentSerializer. Your Feature model already defines a __str__ method that returns the name, so you can use StringRelatedField in the serializer to do this automatically.

Now you just need a view that uses the serializer. The easiest thing here would be to use a ListAPIView, which automatically does everything you need for a list of items. So:

class OpponentSerializer(serializers.ModelSerializer):
    features = serializers.StringRelatedField(many=True, read_only=True)

    class Meta:
        model = Opponent
        fields = ('id', 'features')

class OpponentList(generics.ListAPIView):
    queryset = Opponent.objects.all()
    serializer_class = OpponentSerializer
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.