Reputation: 2585
I have models like following
class Shipment(models.Model):
airwaybill_number = models.IntegerField(primary_key=True)
origin = models.CharField(max_length=50)
destination = models.CharField(max_length=50)
class ShipmentHistory(Models.Model):
airwaybill_number = models.IntegerField(primary_key=True)
last_added_bag = models.CharField(max_length=50, null=True, blank=True)
...
some other fields which can be null
Which one of the following is the best way to update a row in ShipmentHistory table.
Using try / except
try:
history = ShipmentHistory.objects.get(airwaybill_number=1000)
history.last_added_bag = 'abc'
# update other history fields
history.save()
except ShipmentHistory.DoesNotExist:
# create the history record and then update
Using query filter
history = ShipmentHistory.objects.filter(airwaybill_number=1000)
if history.exists()
history[0].last_added_bag = 'abc'
# update other fields
history[0].save()
else:
# create history record first then update
The history records for a particular shipment will be updated atleast a dozen times.
Upvotes: 0
Views: 197
Reputation: 77932
You may want to use Queryset.get_or_create()
(https://docs.djangoproject.com/en/1.7/ref/models/querysets/#get-or-create):
history, created = ShipmentHistory.objects.get_or_create(airwaybill_number=1000)
# update the fields and save..
Upvotes: 2
Reputation: 37924
i have never seen a django model defined like this, i hope, this is only pseudo one
Shipment:
airwaybill_number (pk)
origin (not null)
destination (not null)
and your both queries are two different queries. .get()
vs .filter()
. the later one gives you queryset whereas .get()
gives you an object.
for .get()
you dont have much options to optimize, but you could use get_object_or_404
instead of try/catch. the problem with get()
in your case is you could get MultipleObjectsReturned if there are more than one. thats why i would go for the one with filter().
and yes, .exists()
is cheaper than .count()
.
Upvotes: 2