I have a simple Django Rest Framework API that I would like to return only 1 record. However, when I set many=False
, it no longer works. How can I fix this?
Here's the API: (serializer & model below)
class Expense_View_API(APIView):
permission_classes = [IsAuthenticated, ]
def get(self, request):
param_xid = request.GET.get('id','')
if param_xid != "":
expenses_recordset = Expenses.objects.filter(xid=param_xid)
serializer = Expenses_Serializer(expenses_recordset, many=True)
return Response(serializer.data, status=status.HTTP_200_OK)
else:
return Response("BAD REQUEST: Missing 'id' Parameter", status=status.HTTP_400_BAD_REQUEST)
It returns: (good except that I don't want the square list brackets)
[
{
"xid": 111,
"xdate": "2021-02-15T00:00:00Z",
"xseller": "Amazon",
"xamount": "30.00",
}
]
Problem: When I set serializer = Expenses_Serializer(expenses_recordset, many=False)
, it now returns this null data and drops my xid
field. Why?
{
"xdate": null,
"xseller": null,
"xamount": null,
}
I want it to return:
{
"xid": 111
"xdate": "2021-02-15T00:00:00Z",
"xseller": "Amazon",
"xamount": "30.00",
}
Here's my serializer and data model:
class Expenses_Serializer(serializers.ModelSerializer):
class Meta:
model = Expenses
fields = ('xid', 'xdate', 'xseller', 'xamount')
class Expenses(models.Model):
xid = models.AutoField(db_column='xID', primary_key=True) # Field name made lowercase.
xdate = models.DateTimeField(db_column='xDate', blank=True, null=True) # Field name made lowercase.
xseller = models.CharField(db_column='xSeller', max_length=50, blank=True, null=True) # Field name made lowercase.
xamount = models.DecimalField(db_column='xAmount', max_digits=19, decimal_places=2, blank=True, null=True) # Field name made lowercase.
# Metadata
class Meta:
managed = False
db_table = 'Expenses'
app_label = 'Expenses'
# Methods
def get_absolute_url(self):
"""Returns the url to access a particular instance of MyModelName."""
return reverse('model-detail-view', args=[str(self.id)])
def __str__(self):
"""String for representing the MyModelName object (in Admin site etc.)."""
return self.my_field_name
Thank you for your time!
CodePudding user response:
The problem is that you are serializing a whole QuerySet(list) by using the filter API. Instead, what you want is to serialize a single object instance:
class Expense_View_API(APIView):
permission_classes = [IsAuthenticated, ]
def get(self, request):
param_xid = request.GET.get('id','')
if param_xid != "":
expense_recordset = Expenses.objects.get(xid=param_xid)
serializer = Expenses_Serializer(expense_recordset)
return Response(serializer.data, status=status.HTTP_200_OK)
else:
return Response("BAD REQUEST: Missing 'id' Parameter", status=status.HTTP_400_BAD_REQUEST)
Also, I recommend the use of get_object_or_404 shortcut, to clean up your view.