1

I want to filter the nested data, and these are my serializers and views

Models :

class Employee(models.Model):
    employee_identity = models.CharField(max_length=255, blank=True, null=True)
    full_name = models.CharField(max_length=255, blank=True, null=True)
    place_birth = models.CharField(max_length=255, blank=True, null=True)
    date_birth = models.DateField(blank=True, null=True)
    role = models.CharField(max_length=255, blank=True, null=True)
    no_hp = models.CharField(max_length=255, blank=True, null=True)
    address = models.CharField(max_length=255, blank=True, null=True)
    class Meta:
        managed = False
        db_table = 'employee'

class Penalty(models.Model):
    employee = models.ForeignKey(Employee,on_delete=models.CASCADE)
    type = models.CharField(max_length=255, blank=True, null=True)
    start_date = models.DateField(blank=True, null=True)
    end_date = models.DateField(blank=True, null=True)
    doc = models.CharField(max_length=255, blank=True, null=True)

    class Meta:
        managed = False
        db_table = 'penalty'

Serializers :

class PenaltySerializer (serializers.ModelSerializer):
    employee_identity = serializers.CharField(source="employee.employee_identity")
    month = serializers.SerializerMethodField()
    year = serializers.SerializerMethodField()

    def get_month(self,obj):
        value_start_date = obj.start_date
        month_value = value_start_date.strftime("%b")
        return bulan_value
    def get_year(self,obj):
        value_start_date = obj.start_date
        year_value = value_start_date.strftime("%Y")
        return year_value
    class Meta:
        model = Penalty
        fields = ('id','employee','employee_identity','type','start_date','end_date','month','year') 

class EmployeeSerializer (serializers.ModelSerializer):
    penalty = PenaltySerializer(many=True,read_only=True)

    class Meta:  
        model = Employee
        fields =  ('employee_identity','full_name','penalty')

Views:

class EmployeeViewSet(viewsets.ModelViewSet):
    queryset = Employee.objects.all()
    serializer_class = PegawaiSerializer
    http_method_names = ['get','head']
    pagination_class = LimitPagination

class PenaltyViewSet(viewsets.ModelViewSet): 
    queryset = Penalty.objects.all()
    serializer_class = PenaltySerializer
    http_method_names = ['get','head']
    pagination_class = LimitPagination
    filter_backends = [filters.SearchFilter,DjangoFilterBackend]
    filter_fields = ['employee','type']
    search_fields = ['^start_date']

class DetailDataEmployeeViewSet(viewsets.ModelViewSet):
    queryset = Employee.objects.all()
    serializer_class = EmployeeSerializer
    http_method_names = ['get','head']
    pagination_class = LimitPagination
    filter_backends = [DjangoFilterBackend]
    filterset_fields = ['id','employee_identity']

the result I have without date filter

 "results": [
         {
             "id": 13886,
             "employee_identity": "A3014",
             "full_name": "AAAA",
             "penalty": []
         },
         {
             "id": 13887,
             "employee_identity": "A3015",
             "full_name": "BBB",
             "penalty": [
               {
                     "id": 1,
                     "employee": 20924,
                     "employee_identity": "A3015",
                     "type": "low",
                     "start_date": "2021-01-01",
                     "end_date": "2021-01-02",
                     "month": "Jan",
                     "year": "2021"
                 },
                 {
                     "id": 2,
                     "employee": 20924,
                     "employee_identity": "A3015",
                     "type": "low",
                     "start_date": "2021-02-11",
                     "end_date": "2021-02-12",
                     "month": "Feb",
                     "year": "2021"
                 }
              ]
         }

And the result I want if I filter the data by date (ex: filter date : 2021-01)

"results": [
            {
                "id": 13886,
                "employee_identity": "A3015",
                "full_name": "BBB",
                "penalty": [
                  {
                        "id": 1,
                        "employee": 20924,
                        "employee_identity": "A3015",
                        "type": "low",
                        "start_date": "2021-01-01",
                        "end_date": "2021-01-02",
                        "month": "Jan",
                        "year": "2021"
                    }
                 ]
            }

I can make the result based on DjangoFilterBackend in DetailDataEmployeeViewSet but I don't know how to result penalty data by date. How do i make it happen ? thanks in advance.

0

1 Answer 1

1

An easy solution is to extend filter_queryset method of the ViewSet

class DetailDataEmployeeViewSet(viewsets.ModelViewSet):
    queryset = Employee.objects.all()
    serializer_class = EmployeeSerializer
    http_method_names = ['get','head']
    filter_backends = [DjangoFilterBackend]
    filterset_fields = ['id','employee_identity']

    def filter_queryset(self, queryset):
        queryset = super().filter_queryset(queryset)
        start_date = self.request.query_params.get("start_date", None)

        if start_date is not None:
            print(start_date)
            queryset = queryset.filter(penalty__start_date=start_date)

        return queryset

usage:

GET /employee/?start_date=2021-02-27

Sign up to request clarification or add additional context in comments.

1 Comment

thanks for your answer, but after I filter with 2021-01 , the data in penalty which have start_date 2021-02 also show up. I'm using penalty__start_date__contains=start_date

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.