如何用Django REST API POST请求返回文章列表?解决序列化错误
问题修复方案
你的错误根源是把序列化器实例(ArticleSerializer对象)直接加入了列表,而不是序列化后得到的可JSON序列化的字典数据,同时代码里还有缩进错误、逻辑错位的问题,下面是分步修复:
1. 修正classes.py的代码错误
原代码存在缩进错误,且ArticleList的__init__逻辑混乱,应该只负责初始化属性,不要在里面处理序列化操作:
class Article: def __init__(self, url, title): self.title = title self.url = url class ArticleList: def __init__(self, keywords, articles): self.keywords = keywords self.articles = articles # articles为Article对象的列表
2. 调整序列化器serializers.py
ArticleListSerializer的articles字段需要指定子序列化器,这样才能正确序列化Article对象列表,而非使用普通的ListField:
from rest_framework import serializers import classes class ArticleSerializer(serializers.Serializer): title = serializers.CharField(max_length=300) url = serializers.CharField(max_length=300) def create(self, validated_data): return classes.Article(**validated_data) class ArticleListSerializer(serializers.Serializer): # 指定用ArticleSerializer序列化列表中的每个元素 articles = ArticleSerializer(many=True) keywords = serializers.CharField(max_length=100) def create(self, validated_data): # 处理articles的验证数据,转换为Article对象 articles_data = validated_data.pop('articles') articles = [classes.Article(**item) for item in articles_data] return classes.ArticleList(articles=articles, **validated_data)
3. 重构视图逻辑views.py
你的需求是根据POST传入的关键词生成文章列表,不是创建并保存资源,因此不需要调用serializer.save(),正确逻辑应为:
- 验证请求中的关键词参数
- 根据关键词生成
Article对象列表 - 用
ArticleListSerializer序列化数据后返回
修改后的视图:
from rest_framework.response import Response from rest_framework import status import serializers import classes def article_get(request): if request.method == 'POST': # 验证关键词参数是否存在 keyword = request.data.get('keywords') if not keyword: return Response({"error": "keywords参数必填"}, status=status.HTTP_400_BAD_REQUEST) # 这里替换为你的实际文章生成逻辑:根据keyword生成Article对象列表 # 示例:模拟生成2篇测试文章 generated_articles = [ classes.Article(url="https://example.com/article1", title=f"{keyword}相关文章1"), classes.Article(url="https://example.com/article2", title=f"{keyword}相关文章2") ] # 构造ArticleList对象并序列化 article_list = classes.ArticleList(keywords=keyword, articles=generated_articles) serializer = serializers.ArticleListSerializer(article_list) return Response(serializer.data, status=status.HTTP_200_OK) return Response({"error": "仅支持POST请求"}, status=status.HTTP_405_METHOD_NOT_ALLOWED)
关键说明
- 不要直接将序列化器实例(比如
ArticleSerializer(instance=article))加入列表,要么序列化后取.data得到字典,要么让父序列化器通过many=True自动处理子对象的序列化(后者更简洁) - 你的场景是生成数据返回,不是创建数据库记录,因此不需要调用
serializer.save(),直接构造数据对象后序列化即可 - 原代码中的
serializer.save()会触发ArticleListSerializer的create方法,这不符合你生成文章的需求,因此必须重构视图逻辑
内容的提问来源于stack exchange,提问作者Tico van Hoek
相关产品推荐
相关产品推荐

