【问题标题】:Directly providing foreign key value in djangodjango中直接提供外键值
【发布时间】: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_nameCarType 中的主键,所以第二个代码不会生成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


【解决方案1】:

还有一个额外的字段car_type_id,其中包含外来对象的原始ID。您可以在创建新的 Car 对象时写入它。所以代码:

Car.objects.create(name='Tesla S', car_type_id='sedan')

应该可以正常工作。

【讨论】:

  • 请注意,您也可以使用该字段进行查找。
【解决方案2】:

由于您已将car_type 作为外键,您需要先提供汽车对象,然后声明car_type

c = Car.objects.filter(car_type=CarType.objects.get(code_name='sedan'))
c.car_type = 'sedan'

【讨论】:

    猜你喜欢
    • 2019-01-29
    • 1970-01-01
    • 1970-01-01
    • 2015-08-04
    • 2012-07-07
    • 1970-01-01
    • 2016-04-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多