使用 annotate 或 extra 将外键字段添加到查询集?(相当于 SQL“AS”?)

Mic*_*ary 8 python django django-orm django-queryset

我合并了两个查询集(qs1 和 qs2),它们单独工作正常,如下所示:

qlist = [qs1, qs2]
results = list(chain(qs1, qs2))
Run Code Online (Sandbox Code Playgroud)

到目前为止,一切都很好 - 上面的作品。但现在我正在尝试使用以下命令对结果进行排序:

qlist = [qs1, qs2]
results = sorted(chain(qs1, qs2), key=attrgetter('monthly_fee'))
Run Code Online (Sandbox Code Playgroud)

问题是第二个queryset(qs2)通过ForeignKey引用monthly_fee;而 qs1 有 'monthly_fee' 可用。这是qs2:

qs2 = Offer.objects.select_related('subscription') 
qs2 = qs2.order_by(subscription__monthly_fee) 
Run Code Online (Sandbox Code Playgroud)

以及简化模型:

class Subscription(models.Model): 
    monthly_fee = models.IntegerField(null=False, blank=True, default=0) 
    name = models.CharField(max_length=120, null=True, blank=True)

class Offer(models.Model): 
    promotion_name = models.CharField(max_length=120, null=True, blank=True)
    subscription = models.ForeignKey(Subscription)
    discount = models.IntegerField(null=False, blank=True, default=0) 
Run Code Online (Sandbox Code Playgroud)

我尝试使用 .annotate() 和 .extra()subscription__monthly_fee将查询 qs2 中的重命名如下:

qs2 = Offer.objects.select_related('subscription').annotate(monthly_fee=subscription__monthly_fee)
Run Code Online (Sandbox Code Playgroud)

但是然后得到错误

未定义全局名称“subscription__monthly_fee”

我只是通过覆盖我的模型的 .save() 方法来在创建对象时手动将每月的费用添加到每个 Offer 实例来解决这个问题。但只是想检查是否有更好的方法?

谢谢,

迈克尔

Mar*_*way 10

我以前使用过 F 表达式来实现这种重命名。尝试这个:

from django.db.models import F

qs2 = Offer.objects.select_related('subscription').annotate(monthly_fee=F('subscription__monthly_fee'))
Run Code Online (Sandbox Code Playgroud)