我正在处理django项目,并且有一个Post
模型,该模型具有以下视图:
class PostListApiView(ListCreateAPIView):
queryset = Post.objects.all()
serializer_class = PostSerializer
filter_backends = [SearchFilter]
search_fields = ['user','title','content']
我使用此视图创建新帖子:
@method_decorator(login_required, name='dispatch')
class PostCreateView(APIView):
queryset = Post.objects.all()
serializer_class = PostCreateSerializer
renderer_classes = [TemplateHTMLRenderer]
permission_classes = [IsAuthenticated]
template_name = 'post_form.html'
def get(self, request, format=None):
serializer=PostCreateSerializer()
return Response({'serializer':serializer})
def post(self, request):
serializer = PostCreateSerializer(data=request.data)
if not serializer.is_valid():
return Response({'serializer':serializer})
serializer.save()
return redirect('/')
我想将两个视图合并为一个视图,
class PostListApiView(ListCreateAPIView):
queryset = Post.objects.all()
serializer_class = PostSerializer
filter_backends = [SearchFilter]
search_fields = ['user','title','content']
renderer_classes = [TemplateHTMLRenderer]
template_name = 'post_form.html'
但是当我尝试将TemplateHTMLRenderer
添加到ListCreateAPIView
时,出现此错误:
Traceback (most recent call last):
File "C:\...\lib\site-packages\django\core\handlers\exception.py", line 34, in inner
response = get_response(request)
File "C:\...\lib\site-packages\django\core\handlers\base.py", line 145, in _get_response
response = self.process_exception_by_middleware(e, request)
File "C:\...\lib\site-packages\django\core\handlers\base.py", line 143, in _get_response
response = response.render()
File "C:\...\lib\site-packages\django\template\response.py", line 105, in render
self.content = self.rendered_content
File "C:\...\lib\site-packages\rest_framework\response.py", line 70, in rendered_content
ret = renderer.render(self.data, accepted_media_type, context)
File "C:\...\lib\site-packages\rest_framework\renderers.py", line 167, in render
return template.render(context, request=request)
File "C:\...\lib\site-packages\django\template\backends\django.py", line 59, in render
context = make_context(context, request, autoescape=self.backend.engine.autoescape)
File "C:\...\lib\site-packages\django\template\context.py", line 270, in make_context
raise TypeError('context must be a dict rather than %s.' % context.__class__.__name__)
Exception Type: TypeError at /posts/
Exception Value: context must be a dict rather than ReturnList.
我可以使用TemplateHTMLRenderer
在模板上呈现查询集和表单吗?如何实现?
谢谢
答案 0 :(得分:0)
我遇到了同样的问题并开始调试 DRF 以试图解决这个问题。 DRF 的序列化器、TemplateHTMLRenderer 和 Django 的模板渲染器之间似乎存在某种问题。
就我而言,我正在尝试使用 ListCreateAPIView 来获得默认的获取和创建行为。我想要 json 和 html 响应,所以尝试了这个代码:
class TransactionsController(ListCreateAPIView):
queryset = Transaction.objects.all()
serializer_class = TransactionSerializer
renderer_classes = [TemplateHTMLRenderer]
template_name = 'transactions/index.html'
当尝试访问交易列表时,尽管返回了以下 DRF 文档:
似乎 django\template\context.py 需要一个 dict,但 DRF 序列化程序返回一个 ReturnList (至少当没有从数据库中检索到数据时)。这个空的 ReturnList 由 TemplateHTMLRenderer 处理,后者又调用 django 渲染器,后者抛出异常。
我目前的快速解决方法是:
from rest_framework.generics import ListCreateAPIView
from rest_framework.renderers import TemplateHTMLRenderer
from applications.core.models.transaction import Transaction, TransactionSerializer
class TransactionsTemplateHTMLRender(TemplateHTMLRenderer):
def get_template_context(self, data, renderer_context):
data = super().get_template_context(data, renderer_context)
if not data:
return {}
else:
return data
class TransactionsController(ListCreateAPIView):
queryset = Transaction.objects.all()
serializer_class = TransactionSerializer
renderer_classes = [TransactionsTemplateHTMLRender]
template_name = 'transactions/index.html'
这会检查 DRF 的序列化程序返回的数据,如果为空,则返回一个 dict(而不是默认的 ReturnList)。它有效,但现在我们必须看看从数据库中检索实际数据时会发生什么。
我想在 DRF github 上报告这个是个好主意。