Reputation: 99
My issue is related to Django RestFramework and how to dynamically group objects. The most similar answer I found came from Rex Salisbury here but wasn't adaptable to n number of groups:
models.py
class Product(models.Model):
name = models.CharField(max_length=20)
class Ingredient(models.Model):
name = models.CharField(max_length=20)
class Mix(models.Model):
product = models.ForeignKey(Product, on_delete=models.CASCADE)
ingredient = models.ForeignKey(Ingredient, on_delete=models.CASCADE)
percentage = models.FloatField()
class Meta:
unique_together = ('product', 'ingredient')
serializer.py
class MixSerializer(serializer.ModelSerializer):
class Meta:
model = Mix
fields = ('product', 'liquid', 'percentage')
views.py
class MixView(viewsets.ModelViewSet):
queryset = Mix.objects.all()
serializer_class = MixSerializer
This is an example of the structure I'm currently getting from the API:
[
{
"product": "White Russian",
"ingredient": "Vodka",
"percentage": 0.54
},
{
"product": "White Russian",
"ingredient": "Coffee Liquer",
"percentage": 0.27
},
{
"product": "White Russian",
"ingredient": "Single Cream",
"percentage": 0.19
}
]
I've been trying to group these in a way which minimises the product name repetition, something like this,
{
"product": "White Russian",
"ingredients": {
"Vodka": 0.54,
"Coffee Liquer": 0.27,
"Single Cream": 0.19
}
}
by following documentation for Nested Relationship but I'm no longer convinced this is the right course of action. I'm comfortable getting this data from object filters but unable to implement this alongside the serializers/views.
Upvotes: 3
Views: 529
Reputation: 2943
First note, according to your example you are grouping by product, so you are not looking for a MixView
but for ProductView
.
What you could do:
# Serializers
class MixSerializer(serializer.ModelSerializer):
ingredient_name = serializers.CharField(source='ingredient.name')
class Meta:
model = Mix
fields = ('ingredient_name', 'percentage')
class ProductSerializer(serializer.ModelSerializer):
ingridients = MixSerializer(many=True, read_only=True)
class Meta:
model = Product
fields = ('name', 'ingridients')
# Views
class ProductView(viewsets.ModelViewSet):
queryset = Product.objects.all()
serializer_class = ProductSerializer
Should give you something like:
{
"name": "White Russian",
"ingredients": [
{"ingredient_name": "Vodka", "percentage" : 0.54},
{"ingredient_name": "Coffee Liquer", "percentage" : 0.27},
{"ingredient_name": "Single Cream", "percentage" : 0.19}
]
}
P.S. To make it non read only you will need to also implement create
and update
methods under ProductSerializer
Upvotes: 2