我正在尝试使用 ModelAdmin
上的get_actions()
方法。每个操作都与另一个模型的特定实例相关,并且由于可能添加或删除新实例,我想确保操作列表反映这一点。
这是 ModelAdmin
:(
class PackageAdmin(admin.ModelAdmin):
list_display = ('name', 'quality')
def _actions(self, request):
for q in models.Quality.objects.all():
action = lambda modeladmin, req, qset: qset.update(quality=q)
name = "mark_%s" % (q,)
yield (name, (action, name, "Mark selected as %s quality" % (q,)))
def get_actions(self, request):
return dict(action for action in self._actions(request))
元组返回值的奇怪重复字典由 get_actions()
的 Django 文档。)
正如预期的那样,这会产生一个适当命名的管理操作列表用于将 Quality
外键批量分配给 Package
对象。
问题是,无论我选择哪个操作,相同的Quality
对象都会分配给选定的Package
。
我假设使用 lambda 关键字创建的闭包都包含对同一 q 对象的引用,因此每次迭代都会更改 q 的值> 对于每个功能。
我可以打破这个引用,让我仍然使用包含不同 q
值的闭包列表吗?
编辑:我意识到 lambda
不是在这个例子中是必要的。 我可以简单地
action = lambda modeladmin, req, qset: qset.update(quality=q)
使用 def
:
def action(modeladmin, req, qset):
return qset.update(quality=q)
I am trying to dynamically build a list of admin actions using the get_actions()
method on a ModelAdmin
. Each action relates to a particular instance of another model, and as new instances may be added or removed, I want to make sure the list of actions reflects that.
Here's the ModelAdmin
:
class PackageAdmin(admin.ModelAdmin):
list_display = ('name', 'quality')
def _actions(self, request):
for q in models.Quality.objects.all():
action = lambda modeladmin, req, qset: qset.update(quality=q)
name = "mark_%s" % (q,)
yield (name, (action, name, "Mark selected as %s quality" % (q,)))
def get_actions(self, request):
return dict(action for action in self._actions(request))
(The weird repetitive dict of tuples return value is explained by the Django docs for get_actions()
.)
As expected, this results in a list of appropriately named admin actions for bulk assignment of Quality
foreign keys to Package
objects.
The problem is that whichever action I choose, the same Quality
object gets assigned to the selected Package
s.
I assume that the closures I am creating with the lambda
keyword all contain a reference to the same q
object, so every iteration changes the value of q
for every function.
Can I break this reference, allowing me to still use a list of closures containing different values of q
?
Edit: I realise that lambda
is not necessary in this example. Instead of:
action = lambda modeladmin, req, qset: qset.update(quality=q)
I could simply use def
:
def action(modeladmin, req, qset):
return qset.update(quality=q)
发布评论
评论(3)
如果这不起作用,请尝试
,我怀疑该错误与您使用
yield
有关。也许尝试:try
if that doesn't work, i suspect the bug has something to do with your use of
yield
. maybe try:正如我在对 andylei 的回答的评论中提到的,我刚刚找到了一个解决方案;使用另一个函数来创建闭包似乎会破坏引用,这意味着现在每个操作都引用
Quality
的正确实例。As I mentioned in my comment to andylei's answer, I just found a solution; using another function to create the closure seems to break the reference, meaning that now every action refers to the correct instance of
Quality
.我很惊讶 q 在循环中保持相同的对象。
它可以与您的 lambda 中的
quality=q.id
一起使用吗?I am surprised that q stays the same object within the loop.
Does it work with
quality=q.id
in your lambda?