Is there a way to use refresh_from_db and automatically propagate it on ForeignKey ?
model.py:
class TestItemModel(models.Model):
value = models.IntegerField(default=0)
relies_on_item = models.ForeignKey('self', on_delete=models.SET_NULL, blank=True, null=True )
shell:
>>> end_product = TestItemModel(value=1)
>>> end_product.save()
>>> container_product = TestItemModel(value=10,relies_on_item=end_product)
>>> container_product.save()
>>> end_product.pk
12
>>> end_product_for_update=TestItemModel.objects.get(pk=12)
>>> end_product_for_update.value = 4
>>> end_product_for_update.save()
>>> container_product.relies_on_item.value
1
>>> container_product.refresh_from_db()
>>> container_product.relies_on_item.value
1
The value returned at this point is still the initial one. Is there an option to make refresh_from_db automatically cascade on elements referenced by ForeignKey?
It is possible to do it by explicitly using refresh_from_db on the referenced item - shown below. But I would like to only have to do refresh_from_db on container_product itself.
shell (continued):
>>> container_product.relies_on_item.refresh_from_db()
>>> container_product.relies_on_item.value
4
Introduction to Django Foreign Key. A foreign key is a process through which the fields of one table can be used in another table flexibly. So, two different tables can be easily linked by means of the foreign key. This linking of the two tables can be easily achieved by means of foreign key processes.
str function in a django model returns a string that is exactly rendered as the display name of instances for that model.
To define a one to many relationship in Django models you use the ForeignKey data type on the model that has the many records (e.g. on the Item model).
Use update_fields in save() If you would like to explicitly mention only those columns that you want to be updated, you can do so using the update_fields parameter while calling the save() method. You can also choose to update multiple columns by passing more field names in the update_fields list.
AFAIK In django, Till now refresh_from_db
will not update data for relational fields.It only check whether relation is removed or not. But you can do like (as you did).
for i in container_product._meta.concrete_fields:
if i.is_relation:
getattr(container_product, i.name).refresh_from_db()
OR override refresh_from_db
class Mymodel(models.Model):
def refresh_from_db(self, using=None, fields=None):
super(Mymodel, self).refresh_from_db(using=None, fields=None)
for i in self._meta.concrete_fields:
if i.is_relation and getattr(self, i.name):
getattr(self, i.name).refresh_from_db()
Another solution is to retrieve instance again from DB without using refresh_from_db
.
instance = MyModel.objects.get(pk=pk)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With