What I want to achieve: I want list of
[
{
"location":"Loc 1",
"session":[
{
"start":"2021-01-01",
"counts":600,
"details":[
{
"id":13,
"length_max":21,
"length_min":15,
"length_avg":16,
"length_std":19,
"is_active":false,
"type":"dog"
}
]
}
]
},
{
"location":"Loc3",
"session":[
{
"start":"2021-01-01",
"counts":500,
"details":[
{
"id":15,
"length_max":19,
"length_min":16,
"length_avg":16,
"length_std":19,
"is_active":false,
"type":"dog"
}
]
}
]
}
]
My Viewset is
class SessionFilter(FilterSet):
type_filter = filters.CharFilter(method="filter_by_type")
def filter_by_type(self,queryset,name,value):
queryset = queryset.filter(session__details__type=value).distinct()
return queryset
class SessionModelViewSet(ModelViewSet):
queryset = Session.objects.all()
serializer_class = SessionSerializers
filter_backends = (DjangoFilterBackend,)
filter_class = SessionFilter
I am trying to filter based on type, but am not able to fetch what I need. The out I am getting is
[
{
"location":"Loc 1",
"session":[
{
"start":"2021-01-01",
"counts":600,
"details":[
{
"id":13,
"length_max":21,
"length_min":15,
"length_avg":16,
"length_std":19,
"is_active":false,
"type":"dog"
}
]
},
{
"start":"2021-01-01",
"counts":600,
"details":[
{
"id":7,
"length_max":39,
"length_min":25,
"length_avg":25,
"length_std":27,
"is_active":true,
"type":"cat"
},
{
"id":19,
"length_max":39,
"length_min":25,
"length_avg":25,
"length_std":27,
"is_active":false,
"type":"cat"
}
]
}
]
},
{
"location":"Loc3",
"session":[
{
"start":"2021-01-01",
"counts":500,
"details":[
{
"id":15,
"length_max":19,
"length_min":16,
"length_avg":16,
"length_std":19,
"is_active":false,
"type":"dog"
}
]
},
{
"start":"2021-01-01",
"counts":500,
"details":[
{
"id":9,
"length_max":39,
"length_min":25,
"length_avg":25,
"length_std":27,
"is_active":true,
"type":"cat"
},
{
"id":21,
"length_max":39,
"length_min":25,
"length_avg":25,
"length_std":27,
"is_active":false,
"type":"cat"
}
]
}
]
}
]
How can I customise the filter or change the nested query to fetch the desired output and how can I order by id. Till the second nested level, I am able to fetch data (maybe it is not complicated) but in the 3rd level, I am facing this issue.
Model.py
class Place(models.Model):
id = models.IntegerField(primary_key=True)
location = models.CharField(max_length=100)
class Meta:
db_table = 'place'
managed=False
class Session(models.Model):
id = models.IntegerField(primary_key=True)
place = models.ForeignKey(Place,related_name='session',on_delete=models.CASCADE, null=True)
start = models.DateField(auto_now=True)
counts = models.IntegerField()
class Meta:
db_table = 'session'
managed=False
class Animal(models.Model):
id = models.IntegerField(primary_key=True)
sess = models.ForeignKey(Session,related_name='details',on_delete=models.CASCADE, null=True)
type = models.CharField(max_length=100)
is_active = models.BooleanField()
length_max = models.IntegerField()
length_min = models.IntegerField()
length_avg = models.IntegerField()
length_std = models.IntegerField()
class Meta:
db_table = 'animal'
managed=False
serializer.py
class AnimalSerializers(FlexFieldsModelSerializer):
class Meta:
model = Animal
fields = ["id","length_max","length_min","length_avg","length_std","is_active","type"]
class SessionSerializers(FlexFieldsModelSerializer):
class Meta:
model = Session
fields = ["start","counts","details"]
expandable_fields = {
'details': (AnimalSerializers, {'many': True})
}
class PlaceSerializers(FlexFieldsModelSerializer):
class Meta:
model = Place
fields = ["location","session"]
expandable_fields = {
'session': (SessionSerializers, {'many': True})
}
After prefetch I am getting the json format as
{
"location": "Loc 2",
"session": [
{
"start": "2021-01-01",
"counts": 300,
"details": [
{
"id": 14,
"length_max": 22,
"length_min": 16,
"length_avg": 16,
"length_std": 19,
"is_active": true,
"type": "dog"
}
]
},
{
"start": "2021-01-01",
"counts": 300,
"details": []
}
]
}
is there a way to eliminate and fetch the only one which is required?
After using with filter method, the obtained json format is
.prefetch_related(
Prefetch('session', queryset=Session.objects.filter(details__type=value)),
Prefetch('session__details', queryset=Details.objects.all().order_by('id'))),
)
[
{
"location": "Loc 3",
"session": [
{
"start": "2021-01-01",
"counts": 500,
"details": [
{
"id": 15,
"length_max": 19,
"length_min": 16,
"length_avg": 16,
"length_std": 19,
"is_active": false,
"type": "dog"
}
]
}
]
},
{
"location": "Loc 4",
"session": [
{
"start": "2021-01-02",
"counts": 800,
"details": [
{
"id": 1,
"length_max": 24,
"length_min": 18,
"length_avg": 25,
"length_std": 27,
"is_active": false,
"type": "cat"
},
{
"id": 4,
"length_max": 24,
"length_min": 18,
"length_avg": 25,
"length_std": 27,
"is_active": false,
"type": "cat"
},
{
"id": 16,
"length_max": 24,
"length_min": 18,
"length_avg": 16,
"length_std": 19,
"is_active": false,
"type": "dog"
}
]
},
{
"start": "2021-01-02",
"counts": 800,
"details": [
{
"id": 10,
"length_max": 29,
"length_min": 16,
"length_avg": 16,
"length_std": 19,
"is_active": false,
"type": "dog"
},
{
"id": 22,
"length_max": 29,
"length_min": 16,
"length_avg": 16,
"length_std": 19,
"is_active": false,
"type": "dog"
}
]
}
]
},
Output after updating the code
[
{
"location": "Loc 1",
"session": [
{
"start": "2021-01-01",
"counts": 600,
"details": [
{
"id": 13,
"length_max": 21,
"length_min": 15,
"length_avg": 16,
"length_std": 19,
"is_active": false,
"type": "dog"
}
]
}
]
},
{
"location": "Loc 2",
"session": [
{
"start": "2021-01-01",
"counts": 300,
"details": [
{
"id": 14,
"length_max": 22,
"length_min": 16,
"length_avg": 16,
"length_std": 19,
"is_active": true,
"type": "dog"
}
]
}
]
},
{
"location": "Loc 3",
"session": [
{
"start": "2021-01-01",
"counts": 500,
"details": [
{
"id": 15,
"length_max": 19,
"length_min": 16,
"length_avg": 16,
"length_std": 19,
"is_active": false,
"type": "dog"
}
]
}
]
},
{
"location": "Loc 4",
"session": [
{
"start": "2021-01-02",
"counts": 800,
"details": [
{
"id": 16,
"length_max": 24,
"length_min": 18,
"length_avg": 16,
"length_std": 19,
"is_active": false,
"type": "dog"
}
]
},
{
"start": "2021-01-02",
"counts": 800,
"details": [
{
"id": 10,
"length_max": 29,
"length_min": 16,
"length_avg": 16,
"length_std": 19,
"is_active": false,
"type": "dog"
},
{
"id": 22,
"length_max": 29,
"length_min": 16,
"length_avg": 16,
"length_std": 19,
"is_active": false,
"type": "dog"
}
]
}
]
},
{
"location": "Loc 5",
"session": [
{
"start": "2021-01-02",
"counts": 400,
"details": [
{
"id": 17,
"length_max": 28,
"length_min": 19,
"length_avg": 16,
"length_std": 19,
"is_active": true,
"type": "dog"
}
]
},
{
"start": "2021-01-02",
"counts": 400,
"details": [
{
"id": 11,
"length_max": 38,
"length_min": 28,
"length_avg": 16,
"length_std": 19,
"is_active": false,
"type": "dog"
},
{
"id": 23,
"length_max": 38,
"length_min": 28,
"length_avg": 16,
"length_std": 19,
"is_active": true,
"type": "dog"
}
]
}
]
},
{
"location": "Loc 6",
"session": [
{
"start": "2021-01-02",
"counts": 450,
"details": [
{
"id": 18,
"length_max": 35,
"length_min": 26,
"length_avg": 16,
"length_std": 19,
"is_active": false,
"type": "dog"
}
]
},
{
"start": "2021-01-02",
"counts": 450,
"details": [
{
"id": 12,
"length_max": 15,
"length_min": 13,
"length_avg": 16,
"length_std": 19,
"is_active": true,
"type": "dog"
},
{
"id": 24,
"length_max": 15,
"length_min": 13,
"length_avg": 16,
"length_std": 19,
"is_active": false,
"type": "dog"
}
]
}
]
}
]