Jinesh
Jinesh

Reputation: 2585

Django Query - best way to write query

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.

  1. Do any of the methods have advantages over others, or is there a better way to do this?
  2. Is using a try / except a wrong method of implementation?
  3. Is the query filter option a more expensive query with regards to time?

Upvotes: 0

Views: 197

Answers (2)

bruno desthuilliers
bruno desthuilliers

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

doniyor
doniyor

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

Related Questions