Django:从 ModelAdmin 中访问模型实例?

2023-12-29

我在网上商店应用程序中有一个订单模型,具有自动递增的主键和自身的外键,因为订单可以拆分为多个订单,但必须维护与原始订单的关系。

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 类。对于详细视图,我已包括parent_order in the fieldsets属性。当然,默认情况下,这会在选择框中列出所有订单,但这不是所需的行为。相反,对于没有父订单的订单(即尚未从另一个订单拆分;parent_order为 NULL/None),不应显示任何订单。对于已拆分的订单,这应该仅显示单个父订单。

有一个相当新的 ModelAdmin 方法可用,formfield_for_foreignkey,这似乎很适合这个,因为可以在其中过滤查询集。想象一下,我们正在查看订单 #11234 的详细视图,它已从订单 #11208 中分离出来。代码如下

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 中运行时有效,返回一个单项查询集,其中包含 #11234 的订单 #11208 以及可能已从中拆分的所有其他订单。

当然,我们不能在那里硬编码订单号。我们需要一个参考ordernumber我们正在查看其详细信息页面的订单实例的字段。像这样:

kwargs["queryset"] = Order.objects.filter(child_orders__ordernumber__exact=?????)

我没有找到可行的方法来替换????引用“当前”订单实例,我已经挖得很深了。self inside formfield_for_foreignkey指的是 ModelAdmin 实例,虽然它确实有一个model属性,它不是订单模型实例(它是一个 ModelBase 引用;self.model() 返回一个实例,但其 ordernumber 为 None)。

一种解决方案可能是从 request.path (/admin/orders/order/11234/) 中提取订单号,但这确实很难看。我真的希望有更好的方法。


我认为您可能需要以稍微不同的方式来解决这个问题 - 通过修改 ModelForm,而不是管理类。像这样的东西:

class OrderForm(forms.ModelForm):

    def __init__(self, *args, **kwargs):
        super(OrderForm, self).__init__(*args, **kwargs)
        self.fields['parent_order'].queryset = Order.objects.filter(
            child_orders__ordernumber__exact=self.instance.pk)

class OrderAdmin(admin.ModelAdmin):
    form = OrderForm
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Django:从 ModelAdmin 中访问模型实例? 的相关文章

随机推荐