【问题标题】:Django rest framework foreign key returning as IntegerDjango rest框架外键返回为整数
【发布时间】:2020-07-06 16:04:37
【问题描述】:

我试图用 drf 在 django 中序列化一个模型,但现在我面临的问题是作为外键的作者被作为整数返回。我使用 Vue.js 作为前端。有人请帮忙

序列化器.py:

from rest_framework import serializers
from .models import Post

class PostSerialiers(serializers.ModelSerializer):
    class Meta:
        model = Post
        fields = "__all__"

Views.py:

from django.shortcuts import render
from .models import Post
from .serializers import PostSerialiers
from rest_framework import viewsets

class PostView(viewsets.ModelViewSet):
    queryset = Post.objects.all()
    serializer_class = PostSerialiers

def Home(request):
    return render(request, 'Content/Home.html')

models.py:

from django.db import models

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

class Post(models.Model):
    title = models.CharField(max_length=100, blank=True, null=True)
    caption = models.CharField(max_length=1200, blank=True, null=True)
    author = models.ForeignKey(User, on_delete=models.CASCADE)

模板:

<div v-for="post in obj" style="width: 100%;" class="ui card">
      <div class="content">
        <div class="header">[[post.title]]</div>
        <div class="meta">2 days ago</div>
        <div class="description">
          <p>[[post.caption]]</p>
        </div>
      </div>
      <div class="extra content">
        <i class="check icon"></i>
        [[post.author]]
      </div>
    </div>
    <script>
      function loadDoc() {
        var xhr = new XMLHttpRequest();
        xhr.onreadystatechange = function () {
          if (this.readyState == 4 && this.status == 200) {
            var app = new Vue({
              el: '#root',
              delimiters: ['[[', ']]'],
              data:{
                "obj" : JSON.parse(this.responseText)
              }
            
          })
          }
        }
        xhr.open('GET', 'http://localhost:8000/apiposts/', true);
        xhr.send()
      }

      loadDoc()

    </script>

请大家帮忙

【问题讨论】:

  • 如果您想要该帖子作者的完整详细信息,请在类元中使用 depth=1,然后您可以在 html 中使用 post.author.first_name 或 post.author.last_name, post.author.email
  • @giveJob 不,它不起作用
  • 你通过邮递员检查了吗?如果您在字段下方添加 =“all”,depth=1 应该可以工作,还是有任何错误?
  • @giveJob 不,我没有
  • @giveJob 如果可以,请提供帮助。过去 1 个月左右我一直在为此苦苦挣扎

标签: django vue.js django-models django-rest-framework xmlhttprequest


【解决方案1】:

User创建一个新的serializer

class UserSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        # if you want more fields you can include them
        fields = ('username',)

您必须为Post 模型创建一个新的serializer,因为在检索时您正在寻找usernameemail(无论您使用什么),然后在创建一个新的Post 时再次为您创建一个新的Post想要开箱即用的功能来select 数据库中的用户。理想情况下这是不可能的,因为在后台ForeignKey 使用PrimaryKeyRelatedField 并且当您通过在PostSerializer 中将作者设置为UserSerializer() 来尝试获取username 时,如下所示:

class PostSerialiers(serializers.ModelSerializer):
    author = UserSerializer(many=False)
    class Meta:
        model = Post
        fields = ['title','caption','author']

您将失去在Post 上添加User 的开箱即用功能。因为现在您将处理在UserSerializer 中定义的fields。如果你不这样做;在后台,它将使用PrimaryKeyRelatedField,它会在创建Post 时为您提供选择User 的选项,而在检索数据时您将丢失username。如果您客观地看待,您希望这两个功能都在同一个ViewSet 中。所以你可以有两个不同的serializer 用于两种不同的目的。


class PostSerialiers(serializers.ModelSerializer):
    # this serializer will deal with creating Post with option to select User
    author = serializers.PrimaryKeyRelatedField(queryset=User.objects.all())
    class Meta:
        model = Post
        fields = "__all__"


class NewPostSerializer(serializers.ModelSerializer):
    # this serializer will deal with retrieving data with username/email
    author = UserSerializer(many=False, read_only=True)
    
    class Meta:
        model = Post
        fields = "__all__"

最后,在您的PostView 中,您需要覆盖list(),因为在检索时您需要username 而不是pk,因此您需要使用处理usernameserializer,即NewPostSerializer

views.py

class PostView(viewsets.ModelViewSet):
    queryset = Post.objects.all()
    serializer_class = PostSerialiers

    def list(self, request):
        queryset = self.get_queryset()
        serializer = NewPostSerializer(queryset, many=True)
        return Response(serializer.data) 

【讨论】:

    【解决方案2】:

    在您的 Serializer.py 中,更改以下内容:

    class PostSerialiers(serializers.ModelSerializer):
        class Meta:
            model = Post
            fields = "__all__"
    

    到这里:

    class PostSerialiers(serializers.ModelSerializer):
        author = serializers.StringRelatedField()
        class Meta:
            model = Post
            fields = ['title','caption','author']
    

    【讨论】:

    • 但这并没有让我将用户与帖子相关联。我的意思是当我尝试上传新帖子时,缺少选择作者的选项
    猜你喜欢
    • 2023-03-25
    • 2017-03-27
    • 2021-12-09
    • 2014-09-11
    • 1970-01-01
    • 2017-08-21
    • 2014-10-16
    • 2018-05-22
    相关资源
    最近更新 更多