Django Rest Api - ManyToManyField, Display 'title' instead of 'id' in the Exercises Array

本秂侑毒 提交于 2020-02-26 03:47:45

问题


Django Rest Api - ManyToManyField, Display 'title' instead of 'id' in the Exercises Array

HTTP 200 OK
Allow: GET, POST, PUT, DELETE, PATCH
Content-Type: application/json
Vary: Accept

[
{
    "id": 1,
    "title": "Push Workout Bjarred",
    "description": "Kör Hårt!",
    "exercises": [
        3,
        4,
        5,
        6,
        9,
        10
    ],
    "cardio": [
        4
    ]
},
{
    "id": 2,
    "title": "Pull Workout Loddekopinge",
    "description": "",
    "exercises": [
        1,
        2,
        7,
        8
    ],
    "cardio": []
},
{
    "id": 3,
    "title": "CardioPass",
    "description": "",
    "exercises": [],
    "cardio": [
        2,
        3,
        4
    ]
}
]

Serializer (So I want to display the title and not the id for every exercise)

class WorkoutSerializer(serializers.ModelSerializer):
class Meta:
    model = Workout
    fields = ('id', 'title', 'description', 'exercises', 'cardio')

Here are the models, note that I want to display the exercise name for every exercise in the api array, I don't want the id! - That is passed right now! :)

class Bodypart(models.Model):
name = models.CharField(max_length=100)

def __str__(self):
    return self.name

class Exercise(models.Model):
name = models.CharField(max_length=40)
bodyparts = models.ManyToManyField(Bodypart, blank=True)

def __str__(self):
    return self.name

class Cardio(models.Model):
name = models.CharField(max_length=40)
time = models.IntegerField(default=10)

def __str__(self):
    return self.name

class Meta:
    verbose_name_plural = 'cardio'

class Workout(models.Model):
title = models.CharField(max_length=120)
description = models.CharField(max_length=1000, blank=True)
exercises = models.ManyToManyField(Exercise, blank=True)
cardio = models.ManyToManyField(Cardio, blank=True)

def __str__(self):
    return self.title

回答1:


Create a serializer for the Exercise model with the name field:

class ExerciseSerializer(serializers.ModelSerializer):
    class Meta:
        model = Exercise
        fields = ('name', )

And add it to the Workout serializer:

class WorkoutSerializer(serializers.ModelSerializer):
    exercises = ExerciseSerializer(many=True, read_only=True)
    class Meta:
        fields = ('id', 'title', 'description', 'exercises', 'cardio', )



回答2:


You can get this by changing your WorkoutSerializer like this

class WorkoutSerializer(serializers.ModelSerializer):
    exercises = serializers.StringRelatedField(many=True, read_only=True)
    class Meta:
        fields = ('id', 'title', 'description', 'exercises', 'cardio', )

You will get the result json like this

[
{
    "id": 1,
    "title": "Push Workout Bjarred",
    "description": "Kör Hårt!",
    "exercises": [
        "Exercise 1",
        "Exercise 2",
        "Exercise 4",
        "Exercise 3"
    ],
    "cardio": [
        4
    ]
},
...

More about django rest serializers see https://www.django-rest-framework.org/api-guide/relations/




回答3:


Try adding exercises field in serializer as below exercises = serializers.SlugRelatedField(read_only=True, slug_field='title')




回答4:


I came across the same problem and now I know the answer:

class WorkoutSerializer(serializers.ModelSerializer):
    exercise = serializers.SlugRelatedField(read_only=True, slug_field='name', many=True)
    cardio = serializers.SlugRelatedField(read_only=True, slug_field='name', many=True)
    class Meta:
        fields = ('id', 'title', 'description', 'exercise', 'cardio', )

It must be exercise and cardio which are the exact fields in workout (rather than exercises and cardios. So basically, the answer from Mwangi Kabiru above is correct except that slug_field must be "name" and not title because the fields in class Exercise and Cardio are name, not title.



来源:https://stackoverflow.com/questions/56318324/django-rest-api-manytomanyfield-display-title-instead-of-id-in-the-exerci

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!