代码之家  ›  专栏  ›  技术社区  ›  Ben James

django管理应用程序:构建管理操作的动态列表

  •  3
  • Ben James  · 技术社区  · 15 年前

    我正在尝试使用 get_actions() A方法 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))
    

    (元组返回值的奇怪重复dict由 Django docs for get_actions() )

    如预期的那样,这将导致一个适当命名的管理操作列表,用于批量分配 Quality 外键 Package 物体。

    问题 无论我选择哪种动作,都是一样的吗 质量 对象被分配给选定的 包裹 S.

    我假设我用创建的闭包 lambda 关键字都包含对相同的引用 q 对象,因此每次迭代都会更改 对于 各功能 .

    我可以打破这个引用吗,允许我仍然使用包含不同值的闭包列表 Q ?


    编辑:我意识到 兰姆达 在本例中不需要。而不是:

    action = lambda modeladmin, req, qset: qset.update(quality=q)
    

    我可以简单地使用 def 以下内容:

    def action(modeladmin, req, qset):
        return qset.update(quality=q)
    
    3 回复  |  直到 15 年前
        1
  •  5
  •   andylei    15 年前

    尝试

       def make_action(quality):
            return lambda modeladmin, req, qset: qset.update(quality=quality)
    
       for q in models.Quality.objects.all():
           action = make_action(q)
           name = "mark_%s" % (q,)
           yield (name, (action, name, "Mark selected as %s quality" % (q,)))
    

    如果这不起作用,我怀疑这个bug与你使用 yield . 也许尝试一下:

    def make_action(quality):
        name = 'mark_%s' % quality
        action = lambda modeladmin, req, qset: qset.update(quality=quality)
        return (name, (action, name, "Mark selected as %s quality" % quality))
    
    def get_actions(self, request):
        return dict([make_action for q in models.Quality.objects.all()])
    
        2
  •  1
  •   Ben James    15 年前

    正如我在对andylei答案的评论中提到的,我刚刚找到了一个解决方案;使用另一个函数来创建闭包似乎破坏了引用,这意味着现在每个操作都引用了 Quality .

    def create_action(quality):
        fun = lambda modeladmin, request, queryset: queryset.update(quality=quality)
        name = "mark_%s" % (quality,)
        return (name, (fun, name, "Mark selected as %s quality" % (quality,)))
    
    class PackageAdmin(admin.ModelAdmin):
        list_display = ('name', 'quality')
    
        def get_actions(self, request):
            return dict(create_action(q) for q in models.Quality.objects.all())
    
        3
  •  0
  •   Tobu    15 年前

    我很惊讶Q在循环中保持相同的对象。

    它能用吗 quality=q.id 在你的羊羔里?