Django中通过ID过滤QuerySet并返回JsonResponse的技术问询
嘿,我瞅了下你的Django代码,发现几个关键问题导致它没法正常工作,咱们一步步来搞定:
1. 视图类选得不对
你用了TemplateView,但它的核心定位是渲染HTML模板,而你想要返回JSON数据,这直接导致了流程冲突——TemplateView会默认尝试渲染模板,但你在get_context_data里直接返回了JsonResponse,这肯定会出问题。咱们应该换成更适合处理JSON响应的View类。
2. get_context_data的用法完全错了
get_context_data是TemplateView用来准备模板上下文的方法,根本不是用来返回响应的!而且它的参数签名也不对——第一个参数不是request,正确的写法是def get_context_data(self, **kwargs):。咱们应该重写get方法来处理GET请求,直接返回JSON。
3. QuerySet可以优化一下
虽然values()和filter()的顺序不影响最终结果,但先过滤再指定返回字段会更高效(能减少数据库返回的数据量),所以把filter(id=q)挪到values()前面更好。
修正后的views.py
from django.views import View from django.http import JsonResponse from .models import Reports class MyProfile(View): def get(self, request, *args, **kwargs): pk = kwargs.get('pk') if pk: # 先过滤再取字段,减少数据库查询开销 queryset = Reports.objects.filter(id=pk).values('id', 'line_x', 'line_y') data = list(queryset) return JsonResponse(data, safe=False) # 可以添加pk不存在时的处理逻辑,比如返回空数组或提示信息 return JsonResponse([], safe=False)
可选优化:urls.py的写法
Django 3.0及以上版本推荐用path代替旧的url(url其实是re_path的别名),如果你的Django版本比较新,可以改成这样:
from django.urls import path from . import views urlpatterns = [ path('profiles/<int:pk>/', views.MyProfile.as_view()), ]
要是你还在用旧版本,原来的url(r'^profiles/(?P<pk>\d+)/$', views.MyProfile.as_view())也能正常工作。
额外小提示
如果你之后需要同时实现渲染模板和返回JSON的混合需求,可以考虑用JsonResponseMixin搭配TemplateView,但就你当前的需求来说,直接用View类是最简洁的方案。另外记得处理pk不存在的情况,避免出现意外报错哦~
内容的提问来源于stack exchange,提问作者Mixo

