I have two models:
class PhotoAlbum(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False, auto_created=True)
name = models.CharField(max_length=50, verbose_name='Album name')
class AlbumImage(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False, auto_created=True)
album = models.ForeignKey(PhotoAlbum, on_delete=models.CASCADE, related_name='photos')
image = models.ImageField(upload_to='images/', height_field=None, width_field=None, max_length=100, blank=True)
When i send GET request without query parameters i see a normal response like (one random entry):
[
{
"id": 1,
"name": "Album name",
"photos": [
{
"id": 2,
"url": "http://localhost:8000/media/random_image_one.png"
},
{
"id": 3,
"url": "http://localhost:8000/media/random_image_two.png"
}
]
}
]
And there is a problem! When i overrided the method get_query_set
like:
has_photos = self.request.query_params.get('has_photos')
if has_photos == 'true':
return PhotoAlbum.objects.filter(photos__isnull=False)
elif has_photos == 'false':
return PhotoAlbum.objects.filter(photos__isnull=True)
In the case has_photos = 'true'
i see the response:
[
{
"id": 1,
"name": "Album name",
"photos": [
{
"id": 2,
"url": "http://localhost:8000/media/random_image_one.png"
},
{
"id": 3,
"url": "http://localhost:8000/media/random_image_two.png"
}
]
},
{
"id": 1,
"name": "Album name",
"photos": [
{
"id": 2,
"url": "http://localhost:8000/media/random_image_one.png"
},
{
"id": 3,
"url": "http://localhost:8000/media/random_image_two.png"
}
]
}
]
It returns one entry for each photo object in photos.
So if, the photo album has 10 associated AlbumImage
objects in photos
it returns 10 similar entries instead of 1.
What i did wrong?
I think get_queryset
method has an issue.
You can remove duplicated album
objects with distinct
method.
This problem occurs because a join occurs while evaluating a query.
has_photos = self.request.query_params.get('has_photos')
if has_photos == 'true':
return PhotoAlbum.objects.filter(photos__isnull=False)
elif has_photos == 'false':
return PhotoAlbum.objects.filter(photos__isnull=True)
has_photos = self.request.query_params.get('has_photos')
if has_photos == 'true':
return PhotoAlbum.objects.filter(photos__isnull=False).distinct()
elif has_photos == 'false':
return PhotoAlbum.objects.filter(photos__isnull=True).distinct()
qs = PhotoAlbum.objects.annotate(count=Count('photos'))
has_photos = self.request.query_params.get('has_photos')
if has_photos == 'true':
return qs.filter(count__gte=1)
elif has_photos == 'false':
return qs.filter(count=0)