Alan Tingey
Alan Tingey

Reputation: 971

Django: request.user in form

How may I get the user details to use within a from? I know in the view I can just do:

currentUser=request.user

But if I use it in the form as so I get the following error "'request' is not defined".

class SelectTwoTeams(BootstrapForm):

    currentUser=request.user

    date_joined = currentUser.date_joined.replace(tzinfo=pytz.utc)

    timeless30 = datetime.datetime.now() - datetime.timedelta(seconds=3610)
    timeless30 = timeless30.replace(tzinfo=pytz.utc)

    if date_joined > timeless30:
        currentCharities = forms.ModelChoiceField(queryset=Charity.objects.filter(enabled=1), empty_label=None, widget=forms.Select(attrs={"class":"select-format"}))

    team1 = forms.ModelChoiceField(queryset=StraightredTeam.objects.none(), empty_label=None,
                               widget=forms.Select(attrs={"class":"select-format"}))
    team2 = forms.ModelChoiceField(queryset=StraightredTeam.objects.none(), empty_label=None,
                               widget=forms.Select(attrs={"class":"select-format"}))

Many thanks for any help in advance.

Below shows the init of this form just incase it may help. I know how to get access to the user data using kwargs for this part:

def __init__(self, *args, **kwargs):
    user = kwargs.pop('user', None)
    self.currentSelectedTeam1 = kwargs.pop('currentSelectedTeam1', None)
    self.currentSelectedTeam2 = kwargs.pop('currentSelectedTeam2', None)
    self.currentfixturematchday = kwargs.pop('currentfixturematchday', None)
    self.currentCampaignNo = kwargs.pop('currentCampaignNo', None)
    super(SelectTwoTeams, self).__init__(*args, **kwargs)

    cantSelectTeams = UserSelection.objects.select_related().filter(~Q(fixtureid__fixturematchday=self.currentfixturematchday),campaignno=self.currentCampaignNo, )

    if not cantSelectTeams:
        queryset = StraightredTeam.objects.filter(currentteam = 1).order_by('teamname')
    else:
        queryset = StraightredTeam.objects.filter(currentteam = 1).exclude(teamid__in=cantSelectTeams.values_list('teamselectionid', flat=True)).order_by('teamname')

    teamsAlreadyPlaying = StraightredFixture.objects.filter(soccerseason=1025, fixturematchday=self.currentfixturematchday, fixturedate__lte = timezone.now())
    postponedGames = StraightredFixture.objects.filter(soccerseason=1025, fixturematchday=self.currentfixturematchday,fixturestatus = "P")

    queryset = queryset.exclude(teamid__in=teamsAlreadyPlaying.values_list('home_team_id', flat=True)).order_by('teamname')
    queryset = queryset.exclude(teamid__in=teamsAlreadyPlaying.values_list('away_team_id', flat=True)).order_by('teamname')
    queryset = queryset.exclude(teamid__in=postponedGames.values_list('home_team_id', flat=True)).order_by('teamname')
    queryset = queryset.exclude(teamid__in=postponedGames.values_list('away_team_id', flat=True)).order_by('teamname')

    self.fields['team1'].queryset = queryset
    self.fields['team2'].queryset = queryset
    self.fields['team1'].initial = self.currentSelectedTeam1
    self.fields['team2'].initial = self.currentSelectedTeam2

    self.fields['team1'].label = False
    self.fields['team2'].label = False

    date_joined = user.date_joined.replace(tzinfo=pytz.utc)

    timeless30 = datetime.datetime.now() - datetime.timedelta(seconds=3610)
    timeless30 = timeless30.replace(tzinfo=pytz.utc)

    if date_joined > timeless30:
        self.fields['currentCharities'].label = False

Upvotes: 4

Views: 8989

Answers (3)

Alasdair
Alasdair

Reputation: 309089

The form class is defined when the module is loaded. That means that you can't set currentUser = request.user, since you don't have access to the request object yet. You should remove that line from your code.

The correct approach is to override the __init__ method so that it takes the user. If your field definitions depend on the user then you need to move them into the __init__ method.

class SelectTwoTeams(BootstrapForm):
    def __init__(self, *args, **kwargs):
        self.user = kwargs.pop('user')
        super(SelectTwoTeams, self).__init__(*args, **kwargs)

        date_joined = self.user.date_joined.replace(tzinfo=pytz.utc)

        timeless30 = datetime.datetime.now() - datetime.timedelta(seconds=3610)
        timeless30 = timeless30.replace(tzinfo=pytz.utc)

        if date_joined > timeless30:
            self.fields['currentCharities'] = forms.ModelChoiceField(queryset=Charity.objects.filter(enabled=1))
        ...

You should only use None as the default when popping if the user is not required. It is required in your case, since you access self.user.date_joined in the __init__ method. By storing the user as self.user, you can access it in other methods if required.

Finally, you need to change your view to pass the user when you instantiate the form.

if request.method == "POST"
    form = SelectTwoTeams(request.POST, user=request.user)
    ...
else:
    form = SelectTwoTeams(user=request.user)

Upvotes: 15

Zartch
Zartch

Reputation: 1025

To get any variable in forms you must pass as kwarg argument then get-it in init

In the Form:

class someForm(forms.ModelForm):
    ...code...

    def __init__(self, *args,**kwargs):

        self.Name = kwargs.pop('SomeName')

in your views:

yourform = someForm(request.POST or None, initial={'foo': foo}, SomeName= someVar)

Upvotes: 0

Matheus Veleci
Matheus Veleci

Reputation: 344

You can overwrite the save method and send the request there.

viewys.py

if request.method == "POST"
   if forms.is_valid():
       form.save(request=request.user)

and in your forms.py:

def save(self, request=None, *args, **kwargs
    self.currentUser = request.user
    super(SelectTwoTeams, self).save(*args, **kwargs)
    instance.save()
    return instance

Upvotes: 1

Related Questions