Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
315 views
in Technique[技术] by (71.8m points)

python - Django REST Framework API:无法获取字段的字符串值(Django REST Framework API: Unable to Get String Value of a Field)

I am a beginner in Django.

(我是Django的初学者。)

Right now, I am working with the APIs.

(现在,我正在使用API??。)

I am facing a problem.

(我面临一个问题。)

I can't view the string value one of the fields, called label , at http://127.0.0.1:8000/gameapi/ .

(我无法在http://127.0.0.1:8000/gameapi/上查看名为label的字段之一的字符串值。)

Instead of seeing "label_tag": "racing" , I am seeing "label_tag": [2] .

(我没有看到"label_tag": "racing" ,而是看到了"label_tag": [2] 。)

Here is the screenshot:

(这是屏幕截图:) 在此处输入图片说明

Here are my codes of serializers.py located inside gamreview folder.

(这是我位于gamreview文件夹中的serializers.py代码。)

from rest_framework import serializers
from .models import Game, Tags


# class TagSerializer(serializers.ModelSerializer):
#     class Meta:
#         model = Tags
#         fields = ['label']

class GameSerializer(serializers.ModelSerializer):
    # label_tag = TagSerializer(many=True)
    class Meta:
        model = Game
        # fields = ['id', 'title', 'developer', 'platform']
        fields = ['id', 'title', 'developer', 'platform','label_tag']

def create(self, validated_data):
    label_tag_data = validated_data.pop('label_tag')
    game = Game.objects.create(**validated_data)
    for tags_data in label_tag_data:
        Tags.objects.create(game=game, **tags_data)
    return Game.objects.create(**validated_data)

def update(self, instance, validated_data):
    instance.title = validated_data.get('title', instance.title)
    instance.developer = validated_data.get('developer', instance.developer)
    instance.platform = validated_data.get('platform', instance.platform)
    # instance.tag = TagSerializer(read_only=True, many=True)
    instance.save()
    return instance

Here are my codes of models.py under gamreview folder:

(这是我在gamreview文件夹下的models.py代码:)

from django.db import models
from django.template.defaultfilters import slugify

# Create your models here.

class Tags(models.Model):
    label = models.CharField(max_length=20)

    def __str__(self):
        return self.label


class Game(models.Model):
    title = models.CharField(max_length=100)
    developer = models.CharField(max_length=100)
    platform = models.CharField(max_length=50, default='null')
    label_tag = models.ManyToManyField(Tags)
    slug = models.SlugField(max_length=150, default='null')

    def __str__(self):
        return self.title

    def save(self, *args, **kwargs):
        self.slug = slugify(self.title)
        super().save(*args, **kwargs)


class Review(models.Model):
    game = models.ForeignKey(Game, on_delete=models.CASCADE)
    review = models.CharField(max_length=1000)
    date = models.DateField(auto_now=True)
    slug = models.SlugField(max_length=150, default='null')

    def __str__(self):
        return self.game

Here are my codes of views.py under gamreview folder:

(这是我在gamreview文件夹下的views.py代码:)

from django.views import generic
from .models import Game
from rest_framework import generics
from .serializers import GameSerializer


# Create your views here.


class GameListView(generic.ListView):
    template_name = 'gamereview/gamelist.html'
    context_object_name = 'all_games'

    def get_queryset(self):
        return Game.objects.all()


class ReviewView(generic.DetailView):
    model = Game
    template_name = 'gamereview/review.html'

# class GameApiView(generics.ListAPIView):
class GameApiView(generics.ListCreateAPIView):
    queryset = Game.objects.all()
    serializer_class = GameSerializer

class GameDetailApiView(generics.RetrieveUpdateDestroyAPIView):
    queryset = Game.objects.all()
    serializer_class = GameSerializer

Here are my codes of urls.py under gamreview folder:

(这是我在gamreview文件夹下的urls.py代码:)

from . import views
from django.urls import path

app_name = 'gamereview'

urlpatterns = [
    path('gamereview/', views.GameListView.as_view(), name='gamelist'),
    path('gamereview/<slug:slug>/', views.ReviewView.as_view(), name='review'),
    path('gameapi/', views.GameApiView.as_view(), name='gamelistapi'),
    path('gameapi/<int:pk>/', views.GameDetailApiView.as_view()),


]

I don't get any error while running the server.

(我在运行服务器时没有任何错误。)

However, "label_tag": "racing" is not showing up.

(但是,未显示"label_tag": "racing" 。)

How can I fix the issue?

(我该如何解决该问题?)

  ask by Shawn translate from so

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You can use the source argument

(您可以使用source参数)

 class GameSerializer(serializers.ModelSerializer):
        label_tag = serializers.ReadOnlyField(source='label.label')
        class Meta:
            model = Game
            fields = ['id', 'title', 'developer', 'platform','label_tag']

another way is to use a SerializerMethodField like this(it's an overkill in this case I believe)

(另一种方法是使用像这样的SerializerMethodField(在这种情况下,我认为这是一个过大的杀伤力))

 class GameSerializer(serializers.ModelSerializer):
        label_tag = serializers.SerializerMethodField()
        class Meta:
            model = Game
            fields = ['id', 'title', 'developer', 'platform','label_tag'] 

        def get_label_tag(self, obj):
            return obj.label.label

check similar answers here DRF source argument

(在此处检查类似的答案DRF源参数)


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...