Как получить только связанные объекты в сериализаторе django с помощью manyToMany?
class BookingSerializer(serializers.ModelSerializer):
class Meta:
model = Booking
fields = "__all__"
class EmployeeSerializer(serializers.ModelSerializer):
bookings_st = BookingSerializer(many=True, read_only=True)
class Meta:
model = Employee
fields = "__all__"
class ProjectSerializer(serializers.ModelSerializer):
employees = EmployeeSerializer(read_only=True, many=True)
class Meta:
model = Project
fields = "__all__"
class Employee(models.Model):
name = models.CharField(max_length=127)
lastname = models.CharField(max_length=127)
class Project(models.Model):
title = models.CharField(max_length=127)
employees = models.ManyToManyField(Employee,
related_name='employees')
class Booking(models.Model):
start = models.DateField()
end = models.DateField()
employee = models.ForeignKey(Employee,
on_delete=models.CASCADE,
related_name='bookings_st')
project = models.ForeignKey(Project,
on_delete=models.CASCADE,
related_name='bookings_st')
Я получаю вложенный объект, но как получить в Emploee только связанные с обоими (проектом и сотрудником) бронирования? Сейчас я просто получаю все заказы, которые есть у этого сотрудника. Я имею в виду такую структуру: проект_1: emploee_1: [bookings_that_belong_to_THIS_PROJECT]
Здесь можно использовать SerializerMethodField вместе с объектом сериализатора context:
class BookingSerializer(serializers.ModelSerializer):
class Meta:
model = Booking
fields = "__all__"
class EmployeeSerializer(serializers.ModelSerializer):
bookings_st = serializers.SerializerMethodField()
def get_bookings_st(self, employee):
project = self.context.get("project")
return BookingSerializer(
employee.bookings_st.filter(project=project),
many=True,
).data
class Meta:
model = Employee
fields = "__all__"
class ProjectSerializer(serializers.ModelSerializer):
employees = serializers.SerializerMethodField()
def get_employees(self, project):
return EmployeeSerializer(
project.employees.all(),
many=True,
context={**self.context, "project": project}
).data
class Meta:
model = Project
fields = "__all__"
Это не будет суперпроизводительным, если вы используете это при составлении списка проектов или при получении конкретного проекта с большим количеством сотрудников. В зависимости от вашего сценария использования - если вы используете его только для получения конкретного проекта, например, вы можете использовать prefetch_related и класс Prefetch для предварительной выборки пользовательских наборов запросов сотрудников + бронирований, отфильтровывая конкретный проект (и вы можете затем использовать обычные сериализаторы).