我在网上商店应用程序中有一个Orders模型,它有一个自动递增的主键和一个自己的外键,因为订单可以拆分成多个订单,但必须保持与原始订单的关系.
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
Run Code Online (Sandbox Code Playgroud)
我已经为管理站点注册了OrderAdmin类.对于详细视图,我已经包含parent_order在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)
Run Code Online (Sandbox Code Playgroud)
注释行在Python shell中运行时返回,返回单项查询集,其中包含#11234的#11208订单以及可能已从中拆分的所有其他订单.
当然,我们不能在那里硬编码订单号.我们需要引用ordernumber订单实例的字段,我们正在查看其详细信息页面.像这样:
kwargs["queryset"] = Order.objects.filter(child_orders__ordernumber__exact=?????)
Run Code Online (Sandbox Code Playgroud)
我发现没有办法替换????? 参考"当前"订单实例,我挖得很深.selfinside formfield_for_foreignkey指的是ModelAdmin实例,虽然它确实有一个model属性,但它不是订单模型实例(它是ModelBase引用; self.model()返回一个实例,但它的ordernumber是None).
一个解决方案可能是从request.path(/ admin/orders/order/11234 /)中提取订单号,但这真的很难看.我真的希望有更好的方法.
我已经解决了使用此代码获取对象ID的问题:
class CompanyUserInline(admin.StackedInline):
"""
Defines tabular rules for editing company users direct in company admin
"""
model = CompanyUser
def formfield_for_foreignkey(self, db_field, request, **kwargs):
if db_field.name == "user":
users = User.objects.filter( Q(is_superuser=False) )
query = Q()
for u in users:
aux = CompanyUser.objects.filter(user=u)
if aux.count() == 0:
query |= Q(pk=u.id)
try:
cpu = CompanyUser.objects.filter(company__id=int(request.path.split('/')[4]))
for p in cpu:
query |= Q(pk=p.user.id)
except:
pass
kwargs["queryset"] = User.objects.filter(query).order_by('username')
return super(CompanyUserInline, self).formfield_for_foreignkey(db_field, request, **kwargs)
Run Code Online (Sandbox Code Playgroud)
但是,int(request.path.split('/')[4])真的很难看.我想知道如何从Django AdminModel获取id.我确定它在里面,有谁知道?
先感谢您!; d
您好,我似乎无法在内联表单中过滤外键下拉列表.
这些是我的课程:
class Author(models.Model):
name = models.CharField(max_length=50)
desc = models.CharField(max_length=50)
class Book(models.Model):
author = models.ForeignKey(Author)
title= models.CharField(max_length=50)
class BookPrio::
author = models.ForeignKey(Author)
book = models.ForeignKey(Book)
prio = models.IntegerField()
Run Code Online (Sandbox Code Playgroud)
我的admin.py看起来像:
class BookPrioInline(admin.TabularInline):
model = BookPrio
class AuthorAdmin(admin.ModelAdmin):
inlines =(BookPrioInline,)
admin.site.register(Author, AuthorAdmin)
Run Code Online (Sandbox Code Playgroud)
我希望BookPrio内联的书籍下拉列表可以过滤管理面板中选定的作者.但是可以找出如何做到这一点.
一些帮助将是受欢迎的