Search code examples
pythondjangoformskeyword-argument

Pass username to Django form


I have a custom Form where I need to pass in the request.user.username so I can use that to fill out forms.ModelChoiceField based on what user is accessing it.

Here is what I have

views.py

if request.method == 'POST':
    form = DepartmentForm(request.POST, username=request.user.username)
    # Do stuff
else:
     form = DepartmentForm(username=request.user.username)

forms.py

class DepartmentForm(forms.Form):
    def __init__(self, *args, **kwargs):
        self.username = kwargs.pop('username', None)
        super(DepartmentForm, self).__init__(*args, **kwargs)

    Company = forms.ModelChoiceField(queryset=Company.objects.raw('''
      SELECT DISTINCT c.id, c.name, c.createdBy, c.allowedTeam_ID FROM projects_company AS c
      LEFT JOIN auth_user_groups AS aug ON c.allowedTeam_id=aug.group_id
      LEFT JOIN auth_user AS au ON aug.user_id=au.id
      WHERE au.username = %s OR c.createdBy = %s''',
     [self.username, self.username]),
     empty_label='Select company', widget=forms.Select(attrs={'class': 'materialSelect', 'id': 'companyDropdown'}))

But when I try to select fill out self.username, I get:

NameError: name 'self' is not defined

I tried searching for my solution, but none of the ones I found seem to work. I would appreciate any help you guys can give. If you need more information, please don't hesitate to ask, and I will update the question accordingly.

This is the error I'm getting:

line 25, in DepartmentForm
[self.username, self.username]),
NameError: name 'self' is not defined

Which is the end of the query where I select based on self.username


Solution

  • The line Company = forms.ModelChoiceField() is evaluated when the module is loaded. You don't have access to self.username at that point.

    Instead, you should set the queryset in the form's __init__ method:

    class DepartmentForm(forms.Form):
        company = forms.ModelChoiceField(
            queryset=Company.objects.none(),  # use empty queryset now, we'll set the real queryset when the form is initialised
            widget=forms.Select(...),
        )
    
        def __init__(self, *args, **kwargs):
            self.username = kwargs.pop('username', None)
            super(DepartmentForm, self).__init__(*args, **kwargs)
    
            self.fields['company'].queryset = Company.objects.raw(...)