I have a "PriceTable" object that can contain several "PriceLine" objects with a manytomany relationship.
I use django rest framework to publish an api and I would like that when I use PUT or PATCH on PriceTable, I can also modify the content of PriceLine. The goal is to have a unique UPDATE method to be able to modify the instances of the 2 objects.
My models:
class PriceTable(models.Model):
name = models.CharField(_('Name'), max_length=255)
client = models.ForeignKey(
"client.Client",
verbose_name=_('client'),
related_name="price_table_client",
on_delete=models.CASCADE
)
lines = models.ManyToManyField(
'price.PriceLine',
verbose_name=_('lines'),
related_name="price_table_lines",
blank=True,
)
standard = models.BooleanField(_('Standard'), default=False)
class Meta:
verbose_name = _("price table")
verbose_name_plural = _("price tables")
def __str__(self):
return self.name
class PriceLine(models.Model):
price = models.FloatField(_('Price'))
product = models.ForeignKey(
"client.Product",
verbose_name=_('product'),
related_name="price_line_product",
on_delete=models.CASCADE,
)
class Meta:
verbose_name = _("price line")
verbose_name_plural = _("price line")
def __str__(self):
return f"{self.product.name} : {self.price} €"
I want to be able to send a JSON of this format to modify both the table and its lines:
{
"id": 16,
"lines": [
{
"id": 1,
"price": 20.0,
"product": 1
},
{
"id": 2,
"price": 45.0,
"product": 2
}
],
"name": "test"
}
For this, I try to override the update method of my serializer:
class PriceTableSerializer(serializers.ModelSerializer):
"""
PriceTableSerializer
"""
lines = PriceLineSerializerTest(many=True)
class Meta:
model = PriceTable
exclude = ['standard', 'client',]
def update(self, instance, validated_data):
instance.name = validated_data.get('name', instance.name)
lines = validated_data.get('lines')
print(lines)
# not python code
# for target_line in lines:
# if instance.id == target_line.id
# instance.price = target_line.price
# ...
return instance
The 5 commented lines, are the logic I would like to implement. I want to browse the received array of rows and if the id of this row is equal to the id of a row in my instance, I change the values of this row.
The problem is that the id disappears. When I print the lines variable, I get this:
[OrderedDict([('price', 20.0), ('product', <Product: Test import2>)])]
OrderedDict([('price', 20.0), ('product', <Product: Test import2>)])
What happened to the id?