限制管理面板中的ModelChoiceField选项

时间:2014-07-29 15:49:45

标签: django django-forms django-admin django-guardian

我正在创建一个投票应用程序,它使用管理面板(以及django-guardian),其中模型之间的相关的ForeignKeys链是:

Vote =>
Choice (the choice being voted on) =>
Survey (the survey containing the choice) =>
User (the creator of the survey)

期望的行为:

  • 修改调查的现有投票时,只应向管理员提供该特定调查的选择。
  • 在添加新投票时,管理员应以格式显示他们创建的所有调查中的所有选项 “choice.choice_text(survey.question)”。

下面的代码几乎让我得到了我需要的地方,除了一些事情(对我来说很重要):

  1. 显然,temp_creator需要调用the的所有者 调查,即当前登录的用户(request.user?)。
  2. 当 编辑个人投票,我希望选择列表仅限于 投票所属的特别调查。
  3. 添加新内容时 通过管理面板投票,我希望所有选择都可见,但我会 喜欢将调查问题附加到他们身上,以便用户知道哪一个 他们来自的调查,如果调查共享相同的choice_text。
  4. 这是我的代码:

    # admin.py
    
    class VoteForm(forms.ModelForm):
    
        temp_creator = User.objects.get(pk=2)
        surveys_owned = Survey.objects.filter(creator=temp_creator)
        choice = forms.ModelChoiceField(queryset=Choice.objects.filter(survey__in=surveys_owned))
    
        class Meta:
            model = Vote
    
    class VoteAdmin(GuardedModelAdmin):
    
        fieldsets = [
            ('Required fields', {'fields':['voter_name','choice','rank']}),
        ]
    
        #these lines are for how it's displayed in the admin panel
        list_display = ('voter_name','user_name','choice','rank','date_modified','date_created')
        list_filter = ['choice','rank','date_modified']
        search_fields = ['choice','voter_name','user_name']
    
        form = VoteForm
    
        def queryset(self, request):
            if request.user.is_superuser:
                return super(VoteAdmin, self).queryset(request)
            return get_objects_for_user(user=request.user, perms=['add_vote', 'change_vote', 'delete_vote'], klass=Vote, any_perm=True)
    
        def save_model(self, request, obj, form, change):
            """When creating a new object, set the creator field.
            """
            if not change:
                obj.user_name = request.user
    
            obj.save()
    

1 个答案:

答案 0 :(得分:0)

好吧,我能够部分回答我的问题 - 问题1通过在我的VoteAdmin类中包含this handy function并完全抛弃VoteForm来解决:

def formfield_for_foreignkey(self, db_field, request, **kwargs):
    if db_field.name == "choice":
        surveys_owned = Survey.objects.filter(creator=request.user)
        kwargs["queryset"] = Choice.objects.filter(survey=surveys_owned)
    return super(VoteAdmin, self).formfield_for_foreignkey(db_field, request, **kwargs)

我仍然在处理第二和第三个问题。除非有人在我之前发布决议,否则将在此处发布决议。

编辑:最后通过实施nested inlines来解决问题。对于后人来说,无论如何都能得到答案。