Issue
i want Send the values of several columns of the table ("id", "meter_id", "State", "date", "VII1", "VII2", "VII3", "VII_avg") here is my code:
class VAndI(APIView):
def get(self, request):
queryset = PowerMeter.objects.all().order_by('-id')[:5].values("id", "meter_id", "State", "date", "VII1", "VII2", "VII3", "VII_avg")
serializer = VAndISerializer(instance=queryset, many=True)
return Response(serializer.data, status=status.HTTP_200_OK)
but got this ERROR:
'int' object has no attribute 'pk'
here is my serializer:
class DynamicFieldsModelSerializer(serializers.ModelSerializer):
"""
A ModelSerializer that takes an additional `fields` argument that
controls which fields should be displayed.
"""
def __init__(self, *args, **kwargs):
# Don't pass the 'fields' arg up to the superclass
fields = kwargs.pop('fields', None)
# Instantiate the superclass normally
super().__init__(*args, **kwargs)
if fields is not None:
# Drop any fields that are not specified in the `fields` argument.
allowed = set(fields)
existing = set(self.fields)
for field_name in existing - allowed:
self.fields.pop(field_name)
class VAndISerializer(DynamicFieldsModelSerializer):
class Meta:
model = PowerMeter
fields = ["id", "meter_id", "State", "date", "VII1", "VII2", "VII3", "VII_avg"]
Please note that with this model and serializer, I get the data of all the columns, but in this case, I only want the information of the specified columns.
class VAndI(APIView):
def get(self, request):
queryset = PowerMeter.objects.all().order_by('-id')[:5].values("id", "meter_id", "State", "date", "VII1", "VII2", "VII3", "VII_avg")
serializer = VAndISerializer(instance=queryset, many=True)
return Response(serializer.data, status=status.HTTP_200_OK)
serializer:
class PowerMeterSerializer(serializers.ModelSerializer):
class Meta:
model = PowerMeter
fields = '__all__'
Solution
Please don't use .values()
[django-antipaterns]: .values()
provides dictionaries, and other native types, it is a primitive obsession antipattern [refactoring.guru] and will for example for ForeignKey
s return their primary key, not the corresponding model item.
You thus can work with:
class VAndI(APIView):
def get(self, request):
queryset = PowerMeter.objects.order_by('-id')[:5]
serializer = VAndISerializer(instance=queryset, many=True)
return Response(serializer.data, status=status.HTTP_200_OK)
and if meter_id
is a ForeignKey
, we can add the data in the same query as:
class VAndI(APIView):
def get(self, request):
queryset = PowerMeter.objects.select_related('meter_id').order_by('-id')[
:5
]
serializer = VAndISerializer(instance=queryset, many=True)
return Response(serializer.data, status=status.HTTP_200_OK)
If you want to limit the fields, as your DynamicFieldsModelSerializer
seems to want to do, you are supposed to list the allowed fields when constructing the serializer:
class VAndI(APIView):
def get(self, request):
queryset = PowerMeter.objects.select_related('meter_id').order_by('-id')[
:5
]
serializer = VAndISerializer(
instance=queryset,
many=True,
fields=[
'id',
'meter_id',
'State',
'date',
'VII1',
'VII2',
'VII3',
'VII_avg',
],
)
return Response(serializer.data, status=status.HTTP_200_OK)
Note: In Django, class-based API views (CBV) often have a
…APIView
suffix, to avoid a clash with the model names. Therefore you might consider renaming the view class toVAndIAPIView
, instead of.VAndI
Answered By - willeM_ Van Onsem
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.