如何在Django Rest框架中更改viewset检索响应?
我目前正在开发一个Web应用程序,它使用API作为一个大学项目的后端 我读过DRF是开发和部署API的最快、最简单的方法,我已经遵循了他们的整个官方计划 文档,我似乎不明白如何在他们的视图集和序列化程序中执行以下操作 这里是我的API的一个端点,叫做airports 美国所有可用机场 返回指向美国可用机场的json/csv链接列表如何在Django Rest框架中更改viewset检索响应?,django,python-3.x,django-rest-framework,django-views,api-design,Django,Python 3.x,Django Rest Framework,Django Views,Api Design,我目前正在开发一个Web应用程序,它使用API作为一个大学项目的后端 我读过DRF是开发和部署API的最快、最简单的方法,我已经遵循了他们的整个官方计划 文档,我似乎不明白如何在他们的视图集和序列化程序中执行以下操作 这里是我的API的一个端点,叫做airports 美国所有可用机场 返回指向美国可用机场的json/csv链接列表 URL /机场 方法: GET 成功响应: 代码:200 内容: 显示机场信息 返回指向在特定机场运营的承运人的所有链接,指向特定月份和年份的相关统计数据
- URL
/机场
- 方法:
GET
- 成功响应:
- 代码:200
内容:
- 代码:200
- URL
/airports/:id
- 方法:
GET
- URL参数
必填项:
id=[integer]
- 成功响应:
class Carrier(models.Model):
code = models.CharField(max_length=10)
name = models.TextField()
#airports = models.ManyToManyField(Airport)
def __str__(self):
return self.name
class Airport(models.Model):
code = models.CharField(max_length=10)
name = models.TextField()
carriers = models.ManyToManyField(Carrier, related_name='airports')
def __str__(self):
return self.name
序列化程序:
class AirportSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = models.Airport
fields = ('id', 'name', 'code', 'url')
class CarrierSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = models.Carrier
fields = ('id', 'name', 'code', 'url')
视图:
任何人都有关于我如何使用DRF或我可以使用的任何类型的学习材料来实现这一点的提示吗?如果您想修改ModelViewset的
检索
功能,您可以覆盖其检索
方法,然后做任何您想做的事情<代码>mixin's
如何探索DRF
我认为处理任何新事物的最好方法是他们的代码库。对于ModelViewset,您应该从
视图
开始,探索它提供了哪些功能,以及如何自定义它们 如果您想修改ModelViewset的检索
功能,您可以覆盖其检索
方法并执行任何您想要的操作<代码>mixin's
如何探索DRF
我认为处理任何新事物的最好方法是他们的代码库。对于ModelViewset,您应该从视图
开始,探索它提供了哪些功能,以及如何自定义它们 如上所述,您需要覆盖retrieve
方法,但要做出自定义响应,您需要在Try Except
块中包含self.get\u object()
,因为如果没有它,如果get\u object
失败,它将返回到默认响应,并且没有机会进行自定义所以你可以用这样的东西
首先是自定义响应类(例如,对于失败的情况)
以及
检索
方法def retrieve(self, request, *args, **kwargs):
try:
instance = self.get_object()
except Exception as e:
return ErrorResponse({'message':str(e)})
else:
#any additional logic
serializer = self.get_serializer(instance)
return Response({'data': serializer.data})
如上所述,@需要覆盖retrieve
方法,但要做出自定义响应,需要在Try Except
块中包含self.get\u object()
,因为如果没有它,如果get\u object
失败,它将返回默认响应,并且没有机会自定义它所以你可以用这样的东西
首先是自定义响应类(例如,对于失败的情况)
以及
检索
方法def retrieve(self, request, *args, **kwargs):
try:
instance = self.get_object()
except Exception as e:
return ErrorResponse({'message':str(e)})
else:
#any additional logic
serializer = self.get_serializer(instance)
return Response({'data': serializer.data})
重写retrieve对我不起作用,即使在修改它之后,我也会得到相同的响应,即使我返回“Hello”。@L先生,也许你重写了错误的方法。如果只是返回正在考虑的模型的单个实例,则需要重写
retrieve()
。如果要返回实例列表,请尝试重写list()
方法。您可以在上面答案中共享的mixin链接中找到它的定义。重写retrieve对我不起作用,即使在修改它之后,我也会得到相同的响应,即使我返回“Hello”。@Mr.L可能您重写了错误的方法。如果只是返回正在考虑的模型的单个实例,则需要重写retrieve()
。如果要返回实例列表,请尝试重写list()
方法。您可以在上面答案中共享的mixin链接中找到它的定义。
class AirportList(viewsets.ModelViewSet):
queryset = models.Airport.objects.all()
serializer_class = AirportSerializer
# @Override something here?
class AirportList(viewsets.ModelViewSet):
queryset = models.Airport.objects.all()
serializer_class = AirportSerializer
def retrieve(self, request, *args, **kwargs):
# do your customization here
instance = self.get_object()
serializer = self.get_serializer(instance)
return Response(serializer.data)
class ErrorResponse(Response):
def __init__(self, *args, **kwargs):
super(ErrorResponse,self).__init__(*args, **kwargs)
self.status_code = 404
self.data = {
'success': False,
'message': args[0].get('message')
}
def retrieve(self, request, *args, **kwargs):
try:
instance = self.get_object()
except Exception as e:
return ErrorResponse({'message':str(e)})
else:
#any additional logic
serializer = self.get_serializer(instance)
return Response({'data': serializer.data})