Возвращать null вместо id или вложенных сериализованных данных в ответе API json
Вот код models.py
class Client(models.Model):
name = models.CharField(max_length=255, unique=True)
company_reg_num = models.CharField(max_length=255, blank=True, null=True, unique=True)
date_registerd_internal = models.DateField(auto_now_add=True)
date_registerd_external = models.DateField()
location = models.ManyToManyField(Location, null=True, blank=True, related_name='location')
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, blank=True, null=True)
time_created = models.DateTimeField(auto_now_add=True)
image = models.ImageField(default='default.png', upload_to='profile_imgs', null=True, blank=True)
date_of_birth = models.DateField(blank=True, null=True)
gender = models.CharField(choices=GENDER, max_length=12, default='Male')
place_of_birth = models.CharField(max_length=255, blank=True, null=True)
employer = models.ForeignKey(Client, on_delete=models.CASCADE, blank=True, null=True, related_name='employer')
class Shift(model.Models):
# --snip--
expense = models.ForeignKey(Expense, on_delete=models.CASCADE, null=True, blank=True, related_name='expense')
time_added = models.DateTimeField(auto_now_add=True)
employee_assigned = models.ForeignKey(Profile, on_delete=models.CASCADE, null=True, blank=True, related_name='employee_assigned')
location = models.ForeignKey(Location, on_delete=models.CASCADE, null=True, blank=True)
client = models.ForeignKey(Client, on_delete=models.CASCADE, null=True, blank=True, related_name='client')
И вот мой файл serializer.py
class ProfileSerializer(serializers.ModelSerializer):
class Meta:
model = Profile
fields = '__all__'
class ClientSerializer(serializers.ModelSerializer):
location = LocationSerializer(read_only=True, many=True)
class Meta:
model = Client
fields = '__all__'
class ShiftSerializer(serializers.ModelSerializer):
#permission_classes = [permissions.IsAuthenticatedOrReadOnly]
location = LocationSerializer(read_only=True, many=False)
employee_assigned = ProfileSerializer(many=False, read_only=True)
client = ClientSerializer(many=False, read_only=True)
class Meta:
model = Shift
fields = '__all__'
Я использую представления на основе функций для моих api представлений, и они следующие:
@api_view(['GET', 'POST', 'PATCH'])
@csrf_exempt
@permission_classes((IsAuthenticated,))
def shift_api(request):
if request.method == 'GET':
if request.user.is_superuser and request.user.is_staff:
shifts = Shift.objects.all()
serializer = ShiftSerializer(shifts, many=True)
return Response(serializer.data, status=status.HTTP_200_OK)
else:
return Response({"error": "You do not have permission to view this"}, status=status.HTTP_403_FORBIDDEN)
elif request.method == 'POST':
serializer = ShiftSerializer(data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
elif request.method == 'PATCH':
serializer = ShiftSerializer(data=request.data)
if serializer.is_valid():
serializer.save()
return JsonResponse(json.dumps(serializer.data), status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
@api_view(['GET', 'POST', 'PATCH', 'DELETE'])
def shift_detail_api(request, pk):
try:
shift = Shift.objects.get(pk=pk)
except Shift.DoesNotExist:
return Response({"error": f"no shift found for id of {pk}"},status=status.HTTP_404_NOT_FOUND)
if request.method == 'GET':
serializer = ShiftSerializer(shift)
return Response(serializer.data)
elif request.method == 'PATCH':
serializer = ShiftSerializer(shift, data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
elif request.method == 'DELETE':
shift.delete()
return Response(status=status.HTTP_204_NO_CONTENT)
Когда я запрашиваю API для определенной смены по id, например 22, я получаю вложенный json-ответ следующего вида:
{
"id": 22,
"location": {
"id": 3,
"name": "Lusaka",
"lat": -15.3875259,
"lng": 28.3228165,
"Address": ""
},
"employee_assigned": {
"id": 11,
"time_created": "2022-01-05T18:15:08.109892+02:00",
"image": "/profile_pics/default.png",
"date_of_birth": null,
"gender": "Female",
"place_of_birth": "Yokshire, England",
"phone": null,
"pay_rate": 0.0,
"highest_qualification": null,
"experience_summary": "",
"user": 6,
"employer": 4,
"job_title": 2
},
"client": {
"id": 4,
"location": [
{
"id": 4,
"name": "Kabwe",
"lat": -14.4285061,
"lng": 28.451357,
"Address": ""
}
],
"name": "Kabwe Developers",
"company_reg_num": "3LEA1E7P",
"date_registerd_internal": "2022-01-03",
"date_registerd_external": "2022-01-03",
"industry_category": "SECURITY"
},
"shift_date": "2022-01-05",
"start_time": "2022-01-05T18:51:31+02:00",
"end_time": "2022-01-06T00:45:00+02:00",
"start_of_break": null,
"end_of_break": null,
"break_hours": 0.0,
"start_time_actual": "2022-01-06T18:51:57+02:00",
"end_time_actual": "2022-01-06T20:45:00+02:00",
}
Но когда я хочу добавить смену с помощью метода post, используя существующего клиента и employee_assigned в базе данных, которые в данном случае равны 4 и 13, соответственно, я использую json тело с содержимым ниже:
{
"employee_assigned": 13,
"client": 4,
"shift_date": "2022-01-10",
"start_time": "2022-01-10T06:00:00+02:00",
"end_time": "2022-01-10T14:00:00+02:00",
"start_of_break": null,
"end_of_break": null,
"break_hours": 0.0,
"start_time_actual": null,
"end_time_actual": null,
"clockin_location_lat": null,
"clockin_location_lng": null,
"clockout_location_lat": null,
"clockout_location_lng": null,
"hours_actual": 0.0,
"pay_rate": 0.0,
"charge_rate": 0.0,
"time_added": "2022-01-12T12:49:02.047224+02:00",
"status": "OPEN",
"expense": null
}
Однако я получаю ответ со следующими полями
{
"id": 52,
"location": null,
"employee_assigned": null,
"client": null,
"shift_date": "2022-01-10",
"start_time": "2022-01-10T06:00:00+02:00",
"end_time": "2022-01-10T14:00:00+02:00",
"start_of_break": null,
"end_of_break": null,
"break_hours": 0.0,
"start_time_actual": null,
"end_time_actual": null,
"clockin_location_lat": null,
"clockin_location_lng": null,
"clockout_location_lat": null,
"clockout_location_lng": null,
"hours": 8.0,
"hours_actual": 0.0,
"pay_rate": 0.0,
"charge_rate": 0.0,
"time_added": "2022-01-12T13:13:21.580793+02:00",
"status": "OPEN",
"expense": null
}
Так что я не получаю никаких ошибок, но я хочу, чтобы клиент и назначенный сотрудник возвращали что-то другое, чем null
. Мне нужно, чтобы ответ возвращал либо id, либо вложенные сериализованные данные.
Что я могу сделать, чтобы достичь этого?
из-за того, что вы установили атрибут поля client и employee_assigned read_only в True в вашем классе сериализатора. вы должны определить два разных поля для каждого из них, как показано ниже :
employee_assigned_id = serializer.IntegerField(write_only=True)
employee_assigned = ProfileSerializer(many=False, read_only=True)
cilent_id = serializer.IntegerField(write_only=True)
client = ClientSerializer(many=False, read_only=True)
и затем, когда вы хотите отправить метод POST, отправьте их id, используйте employee_assigned_id, и client_id, и получите их в деталях (whit их serializer)