У меня есть две модели: Задача и Сценарий:
class Task(models.Model):
stakeholder = models.ForeignKey(User, related_name='tasks', blank=True, )
project = models.ForeignKey(Project, related_name='project_tasks' )
title = models.CharField(max_length=50, blank=True, null = True, )
...
class Scenario(models.Model):
stakeholder = models.ForeignKey(User, related_name='scenarios', blank=True,)
tasks = models.ManyToManyField(Task, blank=True)
Их сериалзеры:
class TaskSerializer(serializers.ModelSerializer):
id = serializers.IntegerField()
class Meta:
model = Task
fields = '__all__'
class ScenarioSerializer(serializers.ModelSerializer):
tasks = TaskSerializer(many=True, required=False)
class Meta:
model = Scenario
fields = '__all__'
def create(self, validated_data):
tasks = validated_data.pop('tasks')
instance = Scenario.objects.create(**validated_data)
for task_data in tasks:
task = Task.objects.get(pk=task_data.get('id'))
instance.tasks.add(task)
return instance
def update(self, instance, validated_data):
tasks = validated_data.pop('tasks', [])
instance = super().update(instance, alidated_data)
for task_data in tasks:
task = Task.objects.get(pk=task_data.get('id'))
instance.tasks.add(task)
return instance
И представление для выполнения операций CRUD на обеих этих моделях:
@api_view(['GET', 'POST'])
def task_list(request):
tasks = []
"""
List all tasks, or create a new task.
"""
if request.method == 'GET':
#get all the tasks in aspecific project
if request.query_params.get('projectId'):
# get a specific project
projectId = request.query_params.get('projectId')
project = Project.objects.get(id=projectId)
tasks = project.project_tasks.all()
serializer = TaskSerializer(tasks, many=True)
return Response(serializer.data)
else:
tasks = Task.objects.filter(stakeholder=request.user)
serializer = TaskSerializer(tasks, many=True)
return Response(serializer.data)
elif request.method == 'POST':
serializer = TaskSerializer(data=request.data)
if serializer.is_valid():
serializer.save(stakeholder=request.user)
return Response(serializer.data, status=status.HTTP_201_CREATED)
else:
return Response(
serializer.errors, status=status.HTTP_400_BAD_REQUEST)
@api_view(['GET', 'PUT', 'DELETE'])
def task_detail(request, pk):
"""
Get, udpate, or delete a specific task
"""
try:
task = Task.objects.get(pk=pk)
except Task.DoesNotExist:
return Response(status=status.HTTP_404_NOT_FOUND)
if request.method == 'GET':
serializer = TaskSerializer(task)
return Response(serializer.data)
elif request.method == 'PUT':
serializer = TaskSerializer(task, data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data)
else:
return Response(
serializer.errors, status=status.HTTP_400_BAD_REQUEST)
elif request.method == 'DELETE':
task.delete()
return Response(status=status.HTTP_204_NO_CONTENT)
для сценария:
@api_view(['GET', 'POST'])
def scenarios_list(request):
scenarios = []
"""
List all scenarios, or create a new.
"""
if request.method == 'GET':
# get projects of a specific stakeholder
if request.query_params.get('stakeholderId'):
stakeholderId = request.query_params.get('stakeholderId')
scenarios = Scenario.objects.filter(stakeholder=stakeholderId)
serializer = ScenarioSerializer(scenarios, many=True)
return Response(serializer.data)
else:
scenarios = Scenario.objects.all()
serializer = ScenarioSerializer(scenarios, many=True)
return Response(serializer.data)
elif request.method == 'POST':
serializer = ScenarioSerializer(data=request.data)
if serializer.is_valid():
serializer.save(stakeholder=request.user)
return Response(serializer.data, status=status.HTTP_201_CREATED)
else:
return Response(
serializer.errors, status=status.HTTP_400_BAD_REQUEST)
@api_view(['GET', 'PUT', 'DELETE'])
def scenario_detail(request, pk):
"""
Get, udpate, or delete a specific scenarios
"""
try:
scenario = Scenario.objects.get(pk=pk)
except Project.DoesNotExist:
return Response(status=status.HTTP_404_NOT_FOUND)
if request.method == 'GET':
serializer = ScenarioSerializer(scenario)
return Response(serializer.data)
elif request.method == 'PUT':
serializer = ScenarioSerializer(scenario, data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data)
else:
return Response(
serilizer.errors, status=status.HTTP_400_BAD_REQUEST)
elif request.method == 'DELETE':
scenario.delete()
return Response(status=status.HTTP_204_NO_CONTENT)
Идея заключается в том, что сначала будут созданы задачи, а затем можно создать сценарий, добавив к нему несколько задач.
Создание сценария прошло успешно, но, поскольку я реализовал логику сценариев, создание и обновление задач указали на ошибку, вызвавшую ошибку Bad request.
запрос выглядит следующим образом:
{project: "6", title: "Fourteen", how_often: "", how_important_task: "", role: "", …}
Нужно ли обновлять сериализатор задач? Что не так?
ОБНОВЛЕНИЕ: Если я прокомментирую id = serializers.IntegerField()
в TaskSerializer Создание задачи выполнено успешно, но мне нужна эта строка, в противном случае создание сценария завершится неудачно.