创建一个使用Django Rest Framework返回字符串列表的端点。

huangapple go评论69阅读模式
英文:

Make endpoint that returns a list of strings using Django Rest Framework

问题

我有这个艺术家模型:

class Artist(models.Model):
    name = models.CharField(max_length=100)
    #songs = models.ManyToManyField('Song', related_name='artists')

    def __str__(self):
        return self.name

    class Meta:
        ordering = ('name',)

我想创建一个 API 端点,将所有艺术家的名称作为字符串列表返回,例如:["50 Cent", "Eminem", "Snoop Dogg", ...]。我在我的 urls.py 中创建了这个 artists/names/ URL:

path('artists/names/', views.artist_names, name='artist_names'),

我已经尝试了两种方法:

  1. 使用 Python 列表:
@api_view(['GET'])
def artist_names(request):
    artists = Artist.objects.values_list('name', flat=True)
    artist_names_list = list(artists)
    return Response(artist_names_list)
  1. 在我的 serializers.py 中使用 ListSerializer:
class ArtistNameSerializer(serializers.Serializer):
    name = serializers.ListSerializer(child=serializers.CharField())

在我的 views.py 中,我创建了 artist_names 方法:

@api_view(['GET'])
def artist_names(request):
    artists = Artist.objects.values_list('name', flat=True)
    serializer = ArtistNameSerializer(artists, many=True)
    return Response(serializer.data)

无论从哪种方法,当我访问该端点时,我都得到:

GET /api/artists/names/
HTTP 404 Not Found
Allow: GET, PUT, PATCH, DELETE, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "detail": "Not found."
}

有人可以帮助吗?我做错了什么?

英文:

I have this Artist model:

class Artist(models.Model):
    name = models.CharField(max_length=100)
    #songs = models.ManyToManyField('Song', related_name='artists')

    def __str__(self):
        return self.name

    class Meta:
        ordering = ('name',)

I want to make a api endpoint that returns all the Artists row names as a list of string like for example: ["50 Cent", "Eminem", "Snoop Dogg", ...] . i have created this artists/names/ url in my urls.py:

path('artists/names/', views.artist_names, name='artist_names'),

I have tried two ways already:

  1. Using a python list:
@api_view(['GET'])
def artist_names(request):
    artists = Artist.objects.values_list('name', flat=True)
    artist_names_list = list(artists)
    return Response(artist_names_list)
  1. Using ListSerializer in my serializers.py:
class ArtistNameSerializer(serializers.Serializer):
    name = serializers.ListSerializer(child=serializers.CharField())

and in my views.py i created the artist_names method:

@api_view(['GET'])
def artist_names(request):
    artists = Artist.objects.values_list('name', flat=True)
    serializer = ArtistNameSerializer(artists, many=True)
    return Response(serializer.data)

From both of them when i go to the endpoint i get:

GET /api/artists/names/
HTTP 404 Not Found
Allow: GET, PUT, PATCH, DELETE, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "detail": "Not found."
}

Can someone help? What am i doing wrong?

答案1

得分: 0

我想你对你的方法(1)可能会遇到的问题是,如果不先进行“序列化”,你的Python列表就不是有效的JSON,因此DRF无法正确处理它。

你的方法(2)基本正确,但你在你的“Serializer”类中使用了serializers.ListSerializer,而应该使用serializers.ListField。一旦更正了这一点,你的视图中也不需要使用many=True

以下是我让你的代码正常运行的方式:


serializers.py

from rest_framework import serializers

from .models import Artist

class ArtistSerializer(serializers.Serializer):
    artists = Artist.objects.all()
    names = serializers.ListField(
        child=serializers.CharField(max_length=100),
        default=artists
    )

views.py

from rest_framework.decorators import api_view
from rest_framework.response import Response

from .models import Artist
from .serializers import ArtistSerializer

@api_view(['GET'])
def artist_names(request):
    artists = Artist.objects.all()
    serializer = ArtistSerializer(artists)
    return Response(serializer.data)

urls.py (在应用程序中)

from django.urls import path

from . import views

urlpatterns = [
    path('artists/names/', views.artist_names, name='artist_names'),
]

models.py 文件与你的相同,项目级别的 urls.py 文件包含了 path('', include('app.urls')), 这一行,所以只需确保包含它,并将 app 更改为你的应用程序的名称。

这个代码给我产生的输出如下:

创建一个使用Django Rest Framework返回字符串列表的端点。


希望如果你进行上述调整(看起来主要是对你的序列化程序和视图文件的轻微更改),那么你应该会看到相同的输出!

英文:

I imagine the issue you would have with your method (1) is that without 'serializing' first, your Python list is not valid JSON, so won't be handled correctly by DRF.

Your method (2) is on the right track, but you are using a serializers.ListSerializer inside your 'Serializer' class, where you should be putting a serializers.ListField. You also don't need many=True in your view once this is corrected.

The below is how I got your code working:


serializers.py

from rest_framework import serializers

from .models import Artist


class ArtistSerializer(serializers.Serializer):
    artists = Artist.objects.all()
    names = serializers.ListField(
        child=serializers.CharField(max_length=100),
        default=artists
    )

views.py

from rest_framework.decorators import api_view
from rest_framework.response import Response

from .models import Artist
from .serializers import ArtistSerializer


@api_view(['GET'])
def artist_names(request):
    artists = Artist.objects.all()
    serializer = ArtistSerializer(artists)
    return Response(serializer.data)

urls.py (in app)

from django.urls import path

from . import views


urlpatterns = [
    path('artists/names/', views.artist_names, name='artist_names'),
]

The models.py file is identical to yours, and the project-level urls.py file features the line path('', include('app.urls')),, so just make sure to include that and change app to whatever name your app is.

The output this gave me is below:

创建一个使用Django Rest Framework返回字符串列表的端点。


Hopefully if you make the above adjustments (looks like they are mostly just the minor changes to your serializers and views files I outlined above) then you'll see the same output!

huangapple
  • 本文由 发表于 2023年7月13日 00:26:05
  • 转载请务必保留本文链接:https://go.coder-hub.com/76672685.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定