我在一个网店应用程序中有一个订单模型,它具有自增主键和指向自身的外键,因为订单可以拆分为多个订单,但必须保持与原始订单的关系。
class Order(models.Model):
ordernumber = models.AutoField(primary_key=True)
parent_order = models.ForeignKey('self', null=True, blank=True, related_name='child_orders')
# .. other fields not relevant here
我已经在管理站点中注册了一个 OrderAdmin
类。对于详情视图,我在 fieldsets
属性中包含了 parent_order
。当然,默认情况下,这会将所有订单列在一个选择框中,但这不是期望的行为。相反,对于没有父订单的订单(即未从其他订单分拆的订单;parent_order
为 NULL/None),不应显示任何订单。对于已被拆分的订单,这应该只显示单个父订单。
有一个相当新的 ModelAdmin 方法可用,formfield_for_foreignkey
,似乎非常适合此类问题,因为可以在其中过滤查询集。假设我们正在查看已从订单 #11208 分拆的订单 #11234 的详细信息视图。以下是代码:
def formfield_for_foreignkey(self, db_field, request, **kwargs):
if db_field.name == 'parent_order':
# kwargs["queryset"] = Order.objects.filter(child_orders__ordernumber__exact=11234)
return db_field.formfield(**kwargs)
return super(OrderAdmin, self).formfield_for_foreignkey(db_field, request, **kwargs)
这条被注释的代码在Python shell中运行正常,返回一个包含订单#11208和所有可能从它拆分出来的其他订单的单个查询集。
当然,我们不能在那里硬编码订单号。我们需要引用我们正在查看详细信息页面的订单实例的ordernumber
字段。像这样:
kwargs["queryset"] = Order.objects.filter(child_orders__ordernumber__exact=?????)
我没找到任何可行的方法来用一个引用“当前”Order实例替换 ?????,而且我已经深入挖掘了。在 formfield_for_foreignkey
内部,self
指的是ModelAdmin实例,虽然它有一个model
属性,但它不是订单模型实例(它是一个ModelBase引用;self.model()
返回一个实例,但它的订单号为None)。
一个解决方案可能是从请求路径中提取订单号(/admin/orders/order/11234/),但这样做太丑陋了。我真的希望有更好的方法。
autocomplete_fields
属性,则它将不起作用。 - Mahmood Garibov