2012-01-24 87 views
1

我有一个修改的管理形式,其中我添加了一个字段,应该修改当前模型的父对象的值。现在,根据不同的用户,我需要django的动态操作管理形式

  • 改变,额外的场
  • 设置另一个字段为只读的查询集(或更好,甚至完全隐藏)

基本上我下面的代码按我的预期工作。超级用户获取整个查询集,另一个字段是而不是只读。所有其他用户都获得有限的查询集,而其他字段只读。但是,一旦我在另一个浏览器中打开该网站并且以非超级用户身份打开该网站,即使超级用户也可以获得与非超级用户相同的结果。似乎django以某种方式缓存结果?如果我在条件分支中放置一些打印语句,它们会被正确打印。所以这个方法每次都会被调用,似乎仍然会执行这些步骤。只有错误的结果。

这是一个缓存问题吗?我在做什么完全错误的事情?它可能是django测试服务器中的错误吗?

def get_form(self, request, obj=None, **kwargs): 
    form = super(MultishopProductAdmin, self).get_form(request, obj, **kwargs) 
    if obj is not None: 
     form.declared_fields['categories'].initial = obj.product.category.all() 
    if not request.user.is_superuser: 
     user_site = request.user.get_profile().site 
     form.declared_fields['categories'].queryset = Category.objects.filter(site__id=user_site.id) 
     self.readonly_fields = ('virtual_sites',) 
     if obj is not None: 
      form.declared_fields['categories'].initial = obj.product.category.filter(site__id=user_site.id) 
    return form 

回答

0

所以我找不到一个真正聪明的方法来做我想用django管理员的自定义方法。我现在最终做的是实现管理员的change_view,手动设置我自己的窗体并从那里执行所有我的自定义初始化。

然后,我通过设置change_form_template提供了一个自定义模板,该模板只是扩展了admin/change_form.html,但呈现了我自己的窗体而不是默认窗体。我还设置了extra_context['adminform'] = None,以便删除默认的管理员表单。

这样我现在就可以按我需要的方式定制我的表单,但仍然可以使用所有其他管理员的便利。到目前为止,它似乎很好地工作。不是我认为的最优雅的解决方案,而是我能想到的最好的解决方案。

1

是的,你做错了。在Django 1.2+中,您可以使用get_readonly_fields

this answer

的的ModelAdmin只为它接收的所有请求实例化一次。所以当你定义这样的只读字段时,你会永久性地在整个板上设置它。

关于改变queryset。从文档:

class MyModelAdmin(admin.ModelAdmin): 
    def queryset(self, request): 
     qs = super(MyModelAdmin, self).queryset(request) 
     if request.user.is_superuser: 
      return qs 
     return qs.filter(author=request.user) 
+0

谢谢,那已经解决了我的只读字段问题。然而'queryset'方法并不是我正在寻找的。我通常在categories属性上使用'formfield_for_manytomany'。因为这不是模型的一部分,所以'formfield_for_manytomany'不会被调用。任何其他方法,我可以限制它的查询集呢? – Dennis

+0

当然,也传递它的初始数据。我实际上期望这很简单,但除了通常的初始=参数之外,我找不到任何其他东西,但这并不足以满足我的需求。 – Dennis

+0

你想过滤什么?为什么? –

1

要扩大丹klasson的前面回答:在任意的ModelAdmin方法永远不要设置实例属性(如self.readonly_fields),以防止像你描述的一个问题。只能使用Django ModelAdmin的选项(这是类级别)或方法来操纵任何行为。关于只读字段,您可以使用具有以下签名的ModelAdmin.get_readonly_fields方法:get_readonly_fields(self, request, obj=None)