Django中get_queryset()重写报错排查及代码优化咨询
Let's break down your problem and fix it step by step, plus share some optimizations for your code.
核心报错原因
You're using ListCreateAPIView, a generic view that requires either a queryset class attribute or an overridden get_queryset() method to fetch data. However, you created a custom dataReceive() method instead of overriding get_queryset()—the generic view doesn't recognize this custom method, so it throws the "must override get_queryset()" error.
Additionally, your original dataReceive() had a syntax error: arduino.objects.filter(queryset, name=user) is invalid. The filter() method expects keyword arguments, not a pre-existing queryset as a positional argument.
修复代码:正确重写get_queryset()
For ListCreateAPIView, you don't need a custom method to handle list requests—its built-in list() method will automatically use get_queryset() to fetch data and serialize it with your specified serializer_class. Here's the corrected view:
class arduinoToDatabaseViewSet(ListCreateAPIView): serializer_class = arduinoToDatabaseSerializers # 正确重写get_queryset方法,这是通用视图要求的 def get_queryset(self): user = self.request.user # 直接返回当前用户过滤后的数据集 return arduino.objects.filter(name=user)
This fixes the error because:
- The generic view now has a valid
get_queryset()method to fetch data - The built-in
list()method (handles GET requests) will use this queryset and return the serialized response automatically—no need for your customdataReceive()method.
如果你确实需要自定义接口
If you want a custom endpoint (like dataReceive), use DRF's @action decorator with a ViewSet instead of ListCreateAPIView. This keeps your code aligned with DRF's best practices:
from rest_framework.viewsets import GenericViewSet from rest_framework.mixins import ListModelMixin, CreateModelMixin from rest_framework.decorators import action class arduinoToDatabaseViewSet(ListModelMixin, CreateModelMixin, GenericViewSet): serializer_class = arduinoToDatabaseSerializers # 基础queryset(会被get_queryset覆盖) queryset = arduino.objects.all() def get_queryset(self): return arduino.objects.filter(name=self.request.user) # 自定义动作,会生成类似 /arduino/database/data_receive/ 的路由 @action(detail=False, methods=['get']) def data_receive(self, request): queryset = self.get_queryset() serializer = self.get_serializer(queryset, many=True) return Response(serializer.data)
代码优化建议
Let's clean up your code to follow Python/Django best practices:
Fix naming conventions
- Model classes should use PascalCase: rename
arduinotoArduino - Serializer classes should use PascalCase and singular names: rename
arduinoToAndroidSerializerstoArduinoToAndroidSerializer - View classes should use PascalCase: rename
arduinoToAndroidViewSettoArduinoToAndroidView
- Model classes should use PascalCase: rename
Simplify the first view
YourarduinoToAndroidViewSetusesViewSetbut only returns a list—useListAPIViewinstead for cleaner code:class ArduinoToAndroidView(ListAPIView): serializer_class = ArduinoToAndroidSerializer def get_queryset(self): return Arduino.objects.filter(name=self.request.user)Simplify serializer field
InArduinoToAndroidSerializer, you can replace the customnamefield with a built-in serializer field if yourUsermodel's__str__method returns the username:class ArduinoToAndroidSerializer(serializers.ModelSerializer): name = serializers.StringRelatedField(source='name') class Meta: model = Arduino fields = ('name', 'temp', 'humi')
内容的提问来源于stack exchange,提问作者leedjango

