【发布时间】:2016-05-22 06:46:11
【问题描述】:
考虑这两个模型:
class CarType(models.Model):
code_name = models.SlugField(primary_key=True)
name = models.CharField(max_length=20)
class Car(models.Model):
name = models.CharField(max_length=30)
car_type = models.ForeignKey('CarType')
假设我们想要获取所有轿车,而不是这个查询:
Car.objects.filter(car_type=CarType.objects.get(code_name='sedan'))
我们可以使用这个查询:
sedan_cars = Car.objects.filter(car_type__code_name='sedan')
因为code_name 是CarType 中的主键,所以第二个代码不会生成2 个查询(如第一个),甚至不会使用SQL 连接。
在创建Car 对象时如何做到这一点?天真的方式是这样的:
Car.objects.create(name='Tesla S', car_type=CarType.objects.get(code_name='sedan'))
这将查询CarType 以找出具有条件code_name='sedan' 的行的主键值,并在Car 表的car_type 字段中使用该主键。由于我们已经知道CarType 的主键值,这将是一个非常不必要的额外查询。 (或 django 是否足够聪明,可以避免这种情况?)
如何直接提供car_type值?我尝试了这两个,但都失败了:
Car.objects.create(name='Tesla S', car_type='sedan')
Car.objects.create(name='Tesla S', car_type__code_name='sedan')
【问题讨论】:
-
我会更担心没有增量主键对性能的影响(我很确定这会使查找变得更加困难)。
-
@Sayse 但它在语义上更正确......
-
我没有说错,我只是说它可能会降低索引和查找的性能,可能取决于数据库类型
标签: python django django-models django-queryset django-orm