DB Architecture to store list of images
Question:
I have a model PhotoAlbum
:
class PhotoAlbum(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False, auto_created=True)
name = models.CharField(max_length=50)
And i need to store a list of photos, and when i send a GET request i should see the photos in the format like:
GET /albums
{
'id': 'randomUUID',
'name' : 'MyAlbum'
'photos': [
{
"id": "randomUUID",
"image": "photo.jpg",
},
{
"id": "randomUUID",
"name": "photo2.jpg",
}
]
}
So, to realize this i want to create 2 more models:
class Image(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False, auto_created=True)
image = models.ImageField(upload_to='media/')
class AlbumImage(models.Model):
album = models.ForeignKey(PhotoAlbum, on_delete=models.CASCADE)
image = Image()
And create two serializers: for PhotoAlbum
, and for Image
(to show url).
Is it good solution to solve this task? Can you offer the more optimal?
Answers:
Is the ID relevant for the user? Most likely not. In that case, you can just send an array of URLs. You’d use a StringRelatedField or a MethodField in your serializer.
You should also leverage a ManyToManyField, since your AlbumImage model is simply an association table. If you don’t care for properties of the association, such as ordering, a title or a description, you don’t even have to declare a model (Django creates a table for you behind the scenes).
Make sure to prefetch_related on your queryset, to avoid major performance issues.
A slightly better solution may be to use a serializer that can handle both models, so you don’t need to create two separate serializers. You can use a ModelSerializer
so:
class ImageSerializer(serializers.ModelSerializer):
class Meta:
model = AlbumImage
fields = ['id', 'image']
class PhotoAlbumSerializer(serializers.ModelSerializer):
photos = ImageSerializer(many=True)
class Meta:
model = PhotoAlbum
fields = ['id', 'name', 'photos']
Now, you need to use PhotoAlbumSerializer
to serialize the data and then return the response.
I have a model PhotoAlbum
:
class PhotoAlbum(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False, auto_created=True)
name = models.CharField(max_length=50)
And i need to store a list of photos, and when i send a GET request i should see the photos in the format like:
GET /albums
{
'id': 'randomUUID',
'name' : 'MyAlbum'
'photos': [
{
"id": "randomUUID",
"image": "photo.jpg",
},
{
"id": "randomUUID",
"name": "photo2.jpg",
}
]
}
So, to realize this i want to create 2 more models:
class Image(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False, auto_created=True)
image = models.ImageField(upload_to='media/')
class AlbumImage(models.Model):
album = models.ForeignKey(PhotoAlbum, on_delete=models.CASCADE)
image = Image()
And create two serializers: for PhotoAlbum
, and for Image
(to show url).
Is it good solution to solve this task? Can you offer the more optimal?
Is the ID relevant for the user? Most likely not. In that case, you can just send an array of URLs. You’d use a StringRelatedField or a MethodField in your serializer.
You should also leverage a ManyToManyField, since your AlbumImage model is simply an association table. If you don’t care for properties of the association, such as ordering, a title or a description, you don’t even have to declare a model (Django creates a table for you behind the scenes).
Make sure to prefetch_related on your queryset, to avoid major performance issues.
A slightly better solution may be to use a serializer that can handle both models, so you don’t need to create two separate serializers. You can use a ModelSerializer
so:
class ImageSerializer(serializers.ModelSerializer):
class Meta:
model = AlbumImage
fields = ['id', 'image']
class PhotoAlbumSerializer(serializers.ModelSerializer):
photos = ImageSerializer(many=True)
class Meta:
model = PhotoAlbum
fields = ['id', 'name', 'photos']
Now, you need to use PhotoAlbumSerializer
to serialize the data and then return the response.