Django Query - 编写查询的最佳方式

时间:2014-12-18 08:27:41

标签: python django django-models django-queryset

我有以下模型

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  

以下哪一项是更新ShipmentHistory表中行的最佳方法。

使用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

使用查询过滤器

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

特定货件的历史记录将至少更新十几次。

  1. 这些方法是否优于其他方法,或者有更好的方法吗?
  2. 使用try /除了错误的实现方法吗?
  3. 查询过滤器选项是否是关于时间的更昂贵的查询?

2 个答案:

答案 0 :(得分:2)

我从未见过像这样定义的django模型,我希望,这只是假的

Shipment:
   airwaybill_number (pk)
   origin (not null)
   destination (not null)

并且您的两个查询都是两个不同的查询。 .get() vs .filter()。后一个为您提供查询集,而.get()为您提供一个对象。

.get()您没有太多优化选项,但您可以使用get_object_or_404代替try / catch。在您的情况下get()的问题是,如果有多个问题,您可以获得MultipleObjectsReturned。这就是为什么我会选择filter()。

是的,.exists().count()便宜。

答案 1 :(得分:2)

您可能希望使用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..