Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Limit the choices of a field based on a user

I'd like the form to only show the accounts of the current user in the ChoiceField. I tried doing the following but it doesn't work.

Edit: Sorry, I've forgot to mention the "if kwargs" I added because of the TransForm() not showing any fields. I guess this is wrong but I don't know another way.

views.py:

def in(request, account): 
    if request.method == 'POST':
        form = TransForm(request.user, data=request.POST)
        if form.is_valid():
            ...

    else:
        form = TransForm()

    context = {
          'TranForm': form,
    }
    return render_to_response(
        'cashflow/in.html',
        context,
        context_instance = RequestContext(request),
)

forms.py:

class TransForm(ModelForm):
    class Meta:
        model = Trans

    def __init__(self, *args, **kwargs):
        super(TransForm, self).__init__(*args, **kwargs)
        if kwargs:
            self.fields['account'].queryset = Account.objects.filter(user=args[0])
like image 698
mfalcon Avatar asked Nov 03 '10 22:11

mfalcon


2 Answers

You also need to initialize the form correctly when the request is NO post request:

if request.method == 'POST':
    form = TransForm(user=request.user, data=request.POST)
    if form.is_valid():
        ...

else:
    form = TransForm(user=request.user)
 ...

and furthermore I'd recommend to remove the new argument when calling the superclass' constructor:

class TransForm(ModelForm):
    class Meta:
        model = Trans

    def __init__(self, *args, **kwargs):
        user = kwargs.pop('user')
        super(TransForm, self).__init__(*args, **kwargs)
        self.fields['account'].queryset = Account.objects.filter(user=user)
like image 155
Bernhard Vallant Avatar answered Oct 08 '22 01:10

Bernhard Vallant


Try this in forms.py:

class TransForm(ModelForm):
    class Meta:
        model = Trans

    def __init__(self, user, *args, **kwargs):
        super(TransForm, self).__init__(*args, **kwargs)    
        qs = Account.objects.filter(user=user)
        self.fields['account'] = ModelChoiceField(queryset=qs)

I'm assuming you have imported forms as from django.forms import *.

I'm not sure what exactly is causing your problem, but I suspect two things (quite possibly both):

  1. You are calling the super class' constructor with an unexpected argument (user).
  2. The choices on a ModelChoiceField are determined when the field's constructor runs, which runs as part of the super class' constructor, in which case you setting the queryset after the fact has no effect on the choices.
like image 31
rz. Avatar answered Oct 08 '22 02:10

rz.