django - DRF + SerializerMethodField 与外键
问题描述
与这个问题不同,我不仅想从我的数据中读取数据,SerializerMethodField
而且还想在其中写入数据:
模型:
class Artist(models.Model):
name = models.CharField("name", max_length = 34)
note = models.CharField("additional info", max_length = 128, blank = True, null = True)
class Album(models.Model):
name = models.CharField("name", max_length = 34)
artist = models.ForeignKey(Artist, on_delete=models.CASCADE)
序列化器:
class AlbumSerializer(serializers.ModelSerializer):
artist = serializers.SerializerMethodField("get_artist")
def get_artist(self, obj):
return [obj.artist.pk, obj.artist.name, obj.artist.note]
class Meta:
model = Album
lookup_field = "name"
fields = ["name", "artist",]
read_only_fields = ["name",]
视图集:
class AlbumViewSet(RetrieveModelMixin, ListModelMixin, GenericViewSet):
serializer_class = AlbumSerializer
lookup_field = "name"
def get_queryset(self):
return Album.objects.all()
def retrieve(self, request, artist = None):
query = Album.objects.filter(artist = artist)
results = AlbumSerializer(data = query, many = True)
results.is_valid()
return Response(results.data)
def put(self, request, name):
print("------->", name, request)
return Response("test")
从 API 获取数据工作得很好,但是在调用时api/nevermind
我看到了所有专辑数据,但在 DRF 的可浏览 API 视图中看不到艺术家的下拉菜单。
网址.py:
router = routers.DefaultRouter()
router.register('albums', views.AlbumViewSet, basename = "albums")
urlpatterns = [
path("", views.ListView.as_view(), name = 'index'),
url('^api/', include(router.urls)),
]
解决方案
您不能使用 SerializerMethodField 进行写作。阅读文档中的第一句话。
您需要在这里使用嵌套的序列化程序。像这样的东西:
class ArtistSerializer(serializers.ModelSerializer):
class Meta:
model = Artist
fields = ["id", "name", "note"]
class AlbumSerializer(serializers.ModelSerializer):
artist = ArtistSerializer()
class Meta:
model = Album
lookup_field = "name"
fields = ["name", "artist",]
read_only_fields = ["name",]
请注意,您需要重写 AlbumSerializer 的 save 方法,以便在嵌套序列化程序上进行写入工作。查看文档以获取更多信息。
从 API 获取数据工作得很好,但是在调用 api/nevermind 时,我看到了所有专辑数据,但在 DRF 的可浏览 API 视图中看不到艺术家的下拉菜单。
我很确定您将看不到嵌套序列化程序甚至与 slug/pk 相关的字段的任何类型的下拉列表。这将要求 Django 向服务器/数据库发出额外的请求以获取数据。
不确定我是否可以提出这样的下拉菜单的好方法,我只考虑丑陋的方法。
推荐阅读
- event-handling - 如何在父 Svelte 组件中使用事件委托
- c - strtok 不返回任何值
- microsoft-graph-api - Microsoft Graph API - 获取订阅问题
- python - 根据另一个数据帧的索引从一个数据帧中保留索引
- powershell - Get-child Item Output 的文件夹名称问题
- gitlab - 当 GitLab 的新版本发布时,我如何收到通知电子邮件?
- python - 风格指南:如何在大项目中不陷入混乱
- c - UTF-8 和 ISO8859-1 文件
- azure - 生成用于连接到 azure sql 的令牌需要太长时间
- openmaptiles - tileserver-gl 版本和 Openmaptiles.com 地图数据不匹配?