Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

How to get only related objects in django serializer with 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')

I get nested object, but how to get in Emploee only related to both (project and employee) bookings? Now I just get all bookings that this employee has.
I mean that structure:
project_1:
emploee_1:
[bookings_that_belong_to_THIS_PROJECT]

>Solution :

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

A possibility here is to leverage a SerializerMethodField together with the serializer’s context object:

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__"

This wouldn’t be super performant if you’re using that when listing projects or when retrieving a specific project with many employees. Depending on your use case – if you’re only using it to retrieve a specific project, for example, you could leverage prefetch_related and the Prefetch class to prefetch custom employees + bookings querysets by filtering out the specific project at hand (and you could then use the regular serializers).

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading