Django:从ModelAdmin内访问模型实例? [英] Django: accessing the model instance from within ModelAdmin?
问题描述
我在网上商店应用程序中有一个订单模型,自动递增主键和一个外键自身,因为订单可以分为多个订单,但必须保持与原始订单的关系。
I've got a model for Orders in a webshop application, with an auto-incrementing primary key and a foreign key to itself, since orders can be split into multiple orders, but the relationship to the original order must be maintained.
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),则不应显示任何订单。对于已经拆分的订单,这仅应显示单个父级订单。
I've registered an OrderAdmin class for the admin site. For the detail view, I've included parent_order
in the fieldsets
attribute. Of course, by default this lists all the orders in a select box, but this is not the desired behaviour. Instead, for orders that don't have a parent order (i.e. have not been split from another order; parent_order
is NULL/None), no orders should be displayed. For orders that have been split, this should only display the single parent order.
有一个相当新的ModelAdmin方法可用, formfield_for_foreignkey
,这似乎是完美的,因为queryset可以在其中过滤。想象一下,我们正在查看订单#11234的详细视图,它已从订单#11208拆分。代码在
There's a rather new ModelAdmin method available, formfield_for_foreignkey
, that seems perfect for this, since the queryset can be filtered inside it. Imagine we're looking at the detail view of order #11234, which has been split from order #11208. The code is below
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的单项查询器,以及可能从中拆分的所有其他订单。
The commented row works when run in a Python shell, returning a single-item queryset containing order #11208 for #11234 and all other orders that may have been split from it.
当然,我们不能硬编码在那里的订单号。我们需要引用订单实例的 ordernumber
字段,其详细信息页面正在查看。像这样:
Of course, we can't hard-code the order number there. We need a reference to the ordernumber
field of the order instance whose detail page we're looking at. Like this:
kwargs["queryset"] = Order.objects.filter(child_orders__ordernumber__exact=?????)
我发现没有办法替代参考当前订单实例,我已经挖了很深。 self
in formfield_for_foreignkey
是指ModelAdmin实例,而确实有一个模型
属性,它不是订单模型实例(它是一个ModelBase引用; self.model()返回一个实例,但其顺序号为None)。
I've found no working way to replace ????? with a reference to the "current" Order instance, and I've dug pretty deep. self
inside formfield_for_foreignkey
refers to the ModelAdmin instance, and while that does have a model
attribute, it's not the order model instance (it's a ModelBase reference; self.model() returns an instance, but its ordernumber is None).
一个解决方案可能是从request.path(/ admin / orders / order / 11234 /)中提取订单号,但这真的很丑陋。我真的希望有一个更好的方法。
One solution might be to pull the order number from request.path (/admin/orders/order/11234/), but that is really ugly. I really wish there is a better way.
推荐答案
我认为你可能需要以稍微不同的方式来处理这个 - 通过修改ModelForm,而不是admin类。这样的东西:
I think you might need to approach this in a slightly different way - by modifying the ModelForm, rather than the admin class. Something like this:
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
这篇关于Django:从ModelAdmin内访问模型实例?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!