【发布时间】:2021-08-13 17:34:44
【问题描述】:
我很喜欢在 Django/DRF 中使用 基于类的视图,而不是功能视图。但我认为我的数据库点击量大大增加,从而导致我的 API 变慢。例如:
我有一个端点,它更新或删除在 url 中发送 id 的关注对象。我的观点是这样的。
class UpdateOrderView(UpdateAPIView,DestroyAPIView):
permission_classes = [IsAuthenticated]
queryset = Order.objects.all()
serializer_class = OrderUpdateSerializer
def perform_destroy(self, instance):
instance.delete()
正如我们在上面看到的,我的查询集是 Order 表中的所有对象。如果我打印查询集,它会提供 Order 表中的所有对象,这会使其变慢。
我的网址是:
path('api/updateorder/<int:pk>',views.UpdateOrderView.as_view(),name ='api-updateorder'),
我怎样才能在此处使用 id 获取特定对象?
在功能视图中,我们可以做到这一点。
def Update_or_delete(request,pk)
但是,pk 在基于类的视图中无法识别。
我的序列化器:
class OrderUpdateSerializer(serializers.ModelSerializer):
order_items = OrderItemUpdateSerializer(many=True)
billing_details = BillingDetailsSerializer()
class Meta:
model = Order
fields = ['id','ordered','order_status','order_items','total_price','billing_details']
def update(self, instance, validated_data):
# billing_details_data = validated_data.pop('billing_details', None)
# order_items_data = validated_data.pop('order_items')
#instance = super(OrderUpdateSerializer, self).update(instance,validated_data)
#print(instance)
instance.order_status = validated_data.get('order_status')
instance.ordered = validated_data.get('ordered')
#billing_details_logic
billing_details_data = validated_data.pop('billing_details',None)
if billing_details_data is not None:
instance.billing_details.address = billing_details_data['address']
instance.billing_details.save()
#order_items_logic
instance.save()
#instance.order_items.clear()
order_items_data = validated_data.pop('order_items')
print(order_items_data)
for order_item_data in order_items_data:
oi, created = OrderItem.objects.update_or_create(
id = order_item_data['id'],
defaults={
'quantity' : order_item_data['quantity'],
'order_item_status': order_item_data['order_item_status']
}
)
instance.save()
return super().update(instance,validated_data)
2。我的第二个问题是这个。
许多高级开发人员都喜欢在 Django Rest Framework 中使用 APIView 而不是使用基于通用类的视图,因为人们可以在 APIView 中编写自定义代码,而不是在 CBV 中。例如,所有 CRUD API 都可以集成到 APIView 下的单个 API 中。
上面的说法真的是真的吗??那么,我应该停止使用 CBV 并改用 APIView 吗?我需要一个明确的解释。
【问题讨论】:
-
为该视图提供服务的 url 是什么? pk是其中的一部分吗?
-
我已经在代码中添加了我的网址。是的,我将 pk 作为参数传递。
-
显示
OrderUpdateSerializer(和Order模型)查询集不会减慢您的速度,因为您只处理单个对象(UpdateAPIView和DestroyAPIView处理单个对象)跨度> -
如果我在查询集之后执行打印命令,它会打印所有对象,即我正在查询整个表并带上所有对象。不是吗?? @AbdulAzizBarkat
-
@Django-Rocks
QuerySets 是 lazy 因此在实际需要之前不会进行数据库查询。由于您的视图仅处理单个对象,因此应在此查询集上调用filter或get以仅获取相关对象,因此您可能会在序列化程序中显示 nested 对象,这会减慢您的速度下来。
标签: python django api django-rest-framework django-class-based-views