如何在Django Rest Framework中列出相关对象

3
我是一名有用的助手,可以为您进行文本翻译。以下是需要翻译的内容:

我正在尝试在模型序列化器中添加一个新字段,该字段将显示与另一个模型相关的所有值。

就像我有以下内容:

models.py

from django.db import models

class University(models.Model):
    name = models.CharField(max_length=50)

    def __unicode__(self):
        return self.name

class Student(models.Model):
    first_name = models.CharField(max_length=50)
    last_name = models.CharField(max_length=50)
    university = models.ForeignKey(University)

    def __unicode__(self):
        return '%s %s' % (self.first_name, self.last_name)

views.py

from rest_framework import viewsets
from .models import University, Student
from .serializers import UniversitySerializer, StudentSerializer

class StudentViewSet(viewsets.ModelViewSet):
    queryset = Student.objects.all()
    serializer_class = StudentSerializer

class UniversityViewSet(viewsets.ModelViewSet):
    queryset = University.objects.all()
    serializer_class = UniversitySerializer

serializers.py

from rest_framework import serializers
from .models import University, Student

class UniversitySerializer(serializers.ModelSerializer):
    class Meta:
        model = University

class StudentSerializer(serializers.ModelSerializer):
    class Meta:
        model = Student

urls.py

from rest_framework import routers
from core.views import StudentViewSet, UniversityViewSet
from django.conf import settings
from django.conf.urls import url, include
from django.contrib import admin

router = routers.DefaultRouter()
router.register(r'students', StudentViewSet)
router.register(r'universities', UniversityViewSet)

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^api/', include('apps.core.urls', namespace='core')),
]

现在我正在使用Django Rest Framework编写REST API,所以我会得到像这样的结果。
HTTP 200 OK
Allow: GET, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "students": "http://127.0.0.1:8000/api/students/",
    "universities": "http://127.0.0.1:8000/api/universities/"
}

现在当我点击http://127.0.0.1:8000/api/universities/时,我会得到

HTTP 200 OK
Allow: GET, POST, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

[
    {
        "id": 1,
        "name": "test42"
    },
    {
        "id": 2,
        "name": "xxxxxx1222"
    },
    {
        "id": 3,
        "name": "MIT"
    }
] 

在点击http://127.0.0.1:8000/api/students/后发生以下情况:

HTTP 200 OK
Allow: GET, POST, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

[
    {
        "id": 35,
        "first_name": "Gugu",
        "last_name": "Gaga",
        "university": 11
    },
    {
        "id": 36,
        "first_name": "qwer",
        "last_name": "abcd",
        "university": 12
    }
]

学生有所属的大学,因此我想添加一个学生在大学中的ID列表。

例如:

HTTP 200 OK
Allow: GET, POST, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

[
    {
        "id": 1,
        "name": "test42"
        "students" : {42,56,78}
    },
    {
        "id": 2,
        "name": "xxxxxx1222"
        "students" : {2,6,8}
    },
    {
        "id": 3,
        "name": "MIT"
        "students" : {4,5,7}
    }
] 

如何做到?

2个回答

6
你可以使用PrimaryKeyRelatedField来实现这个功能。首先,将related_name属性设置为你的外键。
university = models.ForeignKey(University, related_name='students')

然后像这样更改您的序列化程序。

class UniversitySerializer(serializers.ModelSerializer):
    students = serializers.PrimaryKeyRelatedField(many=True, read_only=True)
    class Meta:
        model = University

希望这可以帮到你 :)

1
谢谢兄弟!我卡住了,你救了我的排灯节!祝你排灯节快乐 :D - shubhpy
很高兴能帮上忙 :) 愿你有一个愉快的排灯节 :) - Sagar Ramachandrappa

1
您也可以像这样使用related_name属性(不要忘记makemigrations -> migrate):
class Student(models.Model):
    first_name = models.CharField(max_length=50)
    last_name = models.CharField(max_length=50)
    university = models.ForeignKey(University, related_name="students")

现在,在访问UniversitySerializer时,您只需添加新字段名称即可:
class UniversitySerializer(serializers.ModelSerializer):
    class Meta:
        model = University
        fields = ("id", "name", "students",)

这将会精确地返回您所要求的内容,如果您有小型数据集并且总是需要获取相关数据,则可以直接在UniversitySerializer级别对其进行序列化(而不必进行不同的调用),类似于以下内容:

class UniversitySerializer(serializers.ModelSerializer):
    students = StudentSerializer(many=True, read_only=True)
    class Meta:
        model = University
        fields = ("id", "name", "students",)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接