尝试以覆盖ModelChoiceField并被子类化的形式获取request.user,然后查询

时间:2011-06-06 13:03:47

标签: django django-forms

我需要传递一个实例变量(self.rank)供类变量(provider)使用(参见下面注释掉的行)。

注释掉,下面的代码可行。但我很确定我不应该尝试将实例变量传递给类变量。所以我对如何实现我的目标感到茫然,即在ModelChoiceField中动态过滤我的数据。

正如您所看到的,我已经覆盖了ModelChoiceField,因此我可以美化用户名。我还将我的基本SwapForm子类化,因为我还有其他几种形式(这里没有显示)。

另一种说出我需要的方式...我想在我的表单中使用request.user的值,这样我就可以确定该用户的等级,然后按等级过滤掉我的用户以构建一个更小的ModelChoiceField(看起来也不错)。请注意,在我的views.py中,我使用:

调用表单
form = NewSwapForm(request.user)

form = NewSwapForm(request.user, request.POST)

在forms.py中:

from myapp.swaps.models import Swaps
from django.contrib.auth.models import User

class UserModelChoiceField(forms.ModelChoiceField):
    """ Override the ModelChoiceField to display friendlier name """
    def label_from_instance(self, obj):
    return "%s" % (obj.get_full_name())

class SwapForm(forms.ModelForm):
    """ Basic form from Swaps model. See inherited models below. """
    class Meta:
        model = Swaps

class NewSwapForm(SwapForm):
    # Using a custom argument 'user'
    def __init__(self, user, *args, **kwargs):
        super(NewSwapForm, self).__init__(*args, **kwargs)
        self.rank = User.objects.get(id=user.id).firefighter_rank_set.get().rank

    provider = UserModelChoiceField(User.objects.all().
            order_by('last_name').
            filter(firefighter__hirestatus='active')
            ### .filter(firefighter_rank__rank=self.rank)  ###
            )

    class Meta(SwapForm.Meta):
        model = Swaps
        fields = ['provider', 'date_swapped', 'swap_shift']

谢谢!

1 个答案:

答案 0 :(得分:2)

你不能这样做,因为那时self不存在 - 即使你可以,也会在定义时执行,所以对于所有的实例化,等级都是静态的形式。

相反,请在__init__

中执行此操作
provider = UserModelChoiceField(User.objects.none())

 def __init__(self, user, *args, **kwargs):
    super(NewSwapForm, self).__init__(*args, **kwargs)
    rank = User.objects.get(id=user.id).firefighter_rank_set.get().rank # ??
    self.fields['provider'].queryset = User.objects.order_by('last_name').filter(
           firefighter__hirestatus='active', firefighter_rank__rank=rank)

我在rank行旁边放了一个问号,因为rank_set.get()无效......不确定你的意思。