基于Django REST获取外部URL JSON数据 校验POST提交的车辆品牌型号
思路合理性评估
你的初始思路是可行的,但不需要把外部接口的数据提前存入本地模型,完全可以实时拉取后直接比对,减少冗余存储和数据同步成本。如果你的接口调用频率很高,也可以加缓存减少重复请求外部接口,业务量小的场景直接实时请求即可。
具体实现方案
首先你需要安装requests库用于调用外部接口:pip install requests
方案1:在DRF序列化器的校验逻辑中实现(推荐)
如果你的REST API是基于Django REST Framework开发的,把校验逻辑放到序列化器的validate方法中是最佳实践,所有入参校验都会自动执行,不需要在视图中单独判断请求方法,代码结构更清晰。
import requests from rest_framework import serializers from .models import YourModel # 替换为你自己的模型类名 class YourModelSerializer(serializers.ModelSerializer): class Meta: model = YourModel fields = ["brand", "model"] # 替换为你自己的字段 def validate(self, data): # 获取提交的品牌、车型参数,转小写避免大小写不匹配 submit_brand = data.get("brand").lower() submit_model = data.get("model") # 请求外部接口获取对应品牌的车型列表 try: res = requests.get( f"https://vpic.nhtsa.dot.gov/api/vehicles/getmodelsformake/{submit_brand}?format=json", timeout=5 # 加超时避免外部接口异常卡住自身服务 ) res.raise_for_status() model_list = res.json().get("Results", []) except requests.exceptions.RequestException as e: raise serializers.ValidationError("车型校验服务暂时不可用,请稍后重试") # 直接比对无需存入本地模型 is_valid = any(item["Model_Name"] == submit_model for item in model_list) if not is_valid: raise serializers.ValidationError(f"提交的品牌{submit_brand}下不存在该车型,请检查输入") return data
视图层无需额外修改,按原有逻辑写即可,序列化器会自动完成校验。
方案2:原生Django视图层校验实现
如果你还没有使用DRF,直接在视图的POST逻辑中加校验即可:
import requests from django.http import JsonResponse from .models import YourModel # 替换为你自己的模型类名 def your_view(request): if request.method == "POST": # 获取提交参数 submit_brand = request.POST.get("brand").lower() submit_model = request.POST.get("model") # 调用外部接口校验逻辑和上述一致 try: res = requests.get( f"https://vpic.nhtsa.dot.gov/api/vehicles/getmodelsformake/{submit_brand}?format=json", timeout=5 ) res.raise_for_status() model_list = res.json().get("Results", []) except requests.exceptions.RequestException as e: return JsonResponse({"error": "车型校验服务暂时不可用"}, status=503) is_valid = any(item["Model_Name"] == submit_model for item in model_list) if not is_valid: return JsonResponse({"error": "对应品牌下无该车型"}, status=400) # 校验通过后正常存数据 YourModel.objects.create(brand=submit_brand, model=submit_model) return JsonResponse({"status": "success"}, status=201) # 其他请求方法的逻辑保留原有实现即可
可选优化点
- 如果调用外部接口的频率很高,可以加缓存,比如用Django的缓存框架把对应品牌的车型列表缓存1天,避免重复请求,提升响应速度
- 可以对车型名称做模糊匹配或者大小写归一处理,减少校验不通过的误判
- 可以给外部接口请求加降级逻辑,如果外部接口挂了,可以选择暂时放行或者给用户提示,不要影响你的服务正常运行
内容的提问来源于stack exchange,提问作者wolnio
相关产品推荐
相关产品推荐

