You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何基于Django Rest Framework实现动态获取2-4条数据用于对比?

问题描述

我想要开发一个Web应用,允许用户选择对比PostgreSQL数据库中的2、3或4条数据。目前已实现固定获取3条数据的视图函数与URL配置,现询问是否可以编写动态的视图和URL,而非为每种数据数量单独创建视图。

现有固定获取3条数据的实现

视图函数

from myapp.models import Item
from rest_framework.decorators import api_view
from rest_framework.response import Response

@api_view(['GET'])
def get_three_items(request, pk1, pk2, pk3):
    item1 = Item.objects.get(pk=pk1)
    item2 = Item.objects.get(pk=pk2)
    item3 = Item.objects.get(pk=pk3)
    data = [item1.serialize(), item2.serialize(), item3.serialize()]
    return Response(data)

urls.py

from django.urls import path
from .views import get_three_items

urlpatterns = [
    path('items/<int:pk1>/<int:pk2>/<int:pk3>/', get_three_items),
    # ...
]

解决方案

完全可以做到动态处理,不用为2、3、4条数据分别写视图和URL。给你两种靠谱的实现方式:

方案1:用可变数量的URL路径参数

通过多写几个URL规则匹配2-4个主键,然后用同一个视图函数统一处理:

1.1 修改urls.py

from django.urls import path
from .views import compare_items

urlpatterns = [
    # 分别匹配2、3、4个主键的路径
    path('items/<int:pk1>/<int:pk2>/', compare_items),
    path('items/<int:pk1>/<int:pk2>/<int:pk3>/', compare_items),
    path('items/<int:pk1>/<int:pk2>/<int:pk3>/<int:pk4>/', compare_items),
    # ...
]

1.2 编写动态视图函数

from myapp.models import Item
from rest_framework.decorators import api_view
from rest_framework.response import Response
from django.shortcuts import get_object_or_404

@api_view(['GET'])
def compare_items(request, *args):
    # 校验数据数量,只允许2-4条
    if not (2 <= len(args) <= 4):
        return Response({"error": "只能对比2到4条数据"}, status=400)
    
    items = []
    for pk in args:
        # 用get_object_or_404替代get(),找不到数据时返回友好的404响应
        item = get_object_or_404(Item, pk=pk)
        items.append(item.serialize())
    
    return Response(items)

这个方式符合REST风格,直接通过URL路径传递主键,视图用*args接收所有传入的主键,统一处理逻辑。

方案2:用查询参数传递主键

如果不想写多个URL规则,就用查询参数批量传递主键,比如访问items/compare/?pks=1,2,3:

2.1 修改urls.py

from django.urls import path
from .views import compare_items

urlpatterns = [
    path('items/compare/', compare_items),
    # ...
]

2.2 编写视图函数

from myapp.models import Item
from rest_framework.decorators import api_view
from rest_framework.response import Response
from django.shortcuts import get_object_or_404

@api_view(['GET'])
def compare_items(request):
    pks_str = request.query_params.get('pks')
    if not pks_str:
        return Response({"error": "请传递要对比的主键,格式示例:pks=1,2,3"}, status=400)
    
    try:
        # 将逗号分隔的字符串转换为整数主键列表
        pks = list(map(int, pks_str.split(',')))
    except ValueError:
        return Response({"error": "主键必须为整数"}, status=400)
    
    # 校验数据数量
    if not (2 <= len(pks) <= 4):
        return Response({"error": "只能对比2到4条数据"}, status=400)
    
    items = []
    for pk in pks:
        item = get_object_or_404(Item, pk=pk)
        items.append(item.serialize())
    
    return Response(items)

这种方式更灵活,URL规则单一,传参方式更简洁。

小提示

  • 优先用get_object_or_404替代Item.objects.get(),避免主键不存在时抛出500服务器错误,返回更友好的404提示
  • 必须添加数据数量校验,防止用户传入不符合要求的数据量
  • 确保自定义的serialize()方法能正确将模型实例转换为可序列化的JSON格式内容

内容的提问来源于stack exchange,提问作者Hector Devough

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 09:43:34