Python Django REST调用返回对象编号而不是对象名称

时间:2016-09-02 08:19:30

标签: python django django-rest-framework

我是Python新手,我猜我错误地将其序列化了。

这是REST调用结果: enter image description here

  

作者/ models.py:

    from django.db import models
from django.contrib.auth.models import User


# Create your models here.

class Author(models.Model):
    name = models.CharField(max_length=100)
    def __str__(self):
        return self.name


class Book(models.Model):
    auto_increment_id = models.AutoField(primary_key=True)
    name = models.CharField('Book name', max_length=100)
    author = models.ForeignKey(Author, blank=False, null=False, related_name='book_author')
    contents = models.TextField('Contents', blank=False, null=False)
    def __str__(self):
        return self.name
  

作者/ views.py

from authors.models import Book, Author
from authors.serializers import BookSerializer, AuthorSerializer
from django.shortcuts import render
from rest_framework import generics


class ListCreateBooks(generics.ListCreateAPIView):
    queryset = Book.objects.all()
    serializer_class = BookSerializer

class ListCreateAuthor(generics.ListCreateAPIView):
    queryset = Author.objects.all()
    serializer_class = AuthorSerializer
  

作者/ serializers.py

from authors.models import Book, Author
from rest_framework import serializers

class BookSerializer(serializers.ModelSerializer):
    class Meta:
        model = Book
        fields = ('name', 'author')

class AuthorSerializer(serializers.ModelSerializer):
    class Meta:
        model = Author
        book_author = 'name'

我是Django的新手,但我尝试过很多东西,在我的观点中。我已经添加了另一个名为AuthorSerializer的类,它从我在序列化程序中创建的相应类中导入,但后来我意识到我不知道如何将ListCreateAuthor添加到:

 url(r'^api-auth/', ListCreateBooks.as_view(), name='list_books')

我添加了ListCreateAuthor.as_view()的另一个参数,它给了我一个立即错误(这也没有多大意义)我在这里走错路,我该如何解决这个问题?

  

编辑: @Abdulafaja给出了部分答案,它确实解决了这个问题,但是现在检查了一个POST插件后 - 它给出了创建或更新的错误。

Django rest_framework's documentation(@Abdulafaja提供的链接)中,它只给出了嵌套序列化程序的一个示例,它是一对多关系(Album->轨道)但我的是一对一的( book-> author)所以我不知道如何对嵌套功能进行serilize。此API需要为前端提供所有CRUD功能。

感谢。

  

Abdullah编辑的serializers.py:

from authors.models import Book, Author
from rest_framework import serializers


class AuthorSerializer(serializers.ModelSerializer):
    class Meta:
        model = Author
        book_author = 'name'


class BookSerializer(serializers.ModelSerializer):
    author = AuthorSerializer(many=False)

    class Meta:
        model = Book
        fields = ('name', 'author')

        def create(self, validated_data):
            author, _ = Author.objects.get_or_create(name=validated_data.get('author').get('name'))
            return Book.objects.create(name=validated_data.get('name'), author=author)

        def update(self, instance, validated_data):
            author = validated_data.get('author')
            if author:
                instance.author = Author.objects.get_or_create(name=author.get('name'))
            instance.name = validated_data.get('name', instance.name)
            instance.save()
            return instance

2 个答案:

答案 0 :(得分:1)

对于Book model,Author只是数据库中该字段的id,这就是它返回整数字段的原因。 尝试在Book serializer中添加“作者”字段

class BookSerializer(serializers.ModelSerializer):
    author = AuthorSerializer(read_only=True)

    class Meta:
        model = Book
        fields = ('name', 'author')

这是一个NestedSerializer,默认情况下它是只读的。在它上面提到DRF doc site link

  

需要创建create()和/或update()方法,以便明确指定应如何保存子关系。

所以你的BookSerializer需要看起来像这样

class BookSerializer(serializers.ModelSerializer):
    author = AuthorSerializer(read_only=True)

    class Meta:
        model = Book
        fields = ('name', 'author')

    def create(self, validated_data):
        # Create new object

    def update(self, instance, validated_data):
        # Update existing instance

createupdate方法都需要将对象保存到数据库并返回它。保存BookSerializer类实例时会调用它。 它们之间的区别在于,当您创建Book对象的新实例

时,会调用create
serializer = BookSerializer(data=data)
如果在实例化序列化程序类时传递了Book对象的现有实例,则会调用

update

serializer = BookSerializer(book, data=data)

您可以找到更多信息here

修改 如果要使用NestedSerializer创建实例,则它不应该是只读字段。

class BookSerializer(serializers.ModelSerializer):
    author = AuthorSerializer(many=False)

    class Meta:
        model = Book
        fields = ('name', 'author')

    def create(self, validated_data):
        author, _ = Author.objects.get_or_create(name=validated_data.get('author').get('name'))
        return Book.objects.create(name=validated_data.get('name'), author=author)

    def update(self, instance, validated_data):
        author = validated_data.get('author')
        if author:
            instance.author = Author.objects.get_or_create(name=author.get('name'))
        instance.name = validated_data.get('name', instance.name)
        instance.save()
        return instance

答案 1 :(得分:0)

根据我的理解,您希望在api请求中获取作者的详细信息,而不仅仅是他们的数字?

这样做的方法是在模型序列化器中设置深度。


class BookSerializer(serializers.ModelSerializer):
    class Meta:
        model = Book
        fields = ('name', 'author')
        depth=1

深度选项应设置为整数值,该值指示在还原为平面表示之前应该遍历的关系深度。即1,2,3 ......

来源:http://www.django-rest-framework.org/api-guide/serializers/