ApPeL
ApPeL

Reputation: 4921

How can I access request.user from within a Django form's methods?

My form looks as follows:

from django.forms import ModelForm
from django import forms
from models import Trophies
from gunsafe.models import Gun
from django.contrib.auth.models import User

class TrophiesForm(request.user, ModelForm):
    used_his = forms.ModelMultipleChoiceField(
        queryset=Gun.objects.filter(user__id=1)
    )
    
    def __init__(self, user, *args, **kwargs):
        super(TrophiesForm, self).__init__(*args, **kwargs)
        self.fields['used_his'].queryset = User.objects.filter(pk = user)

I was wondering how I can get the current logged in users ID instead of the user__id=1

Upvotes: 10

Views: 28106

Answers (2)

ButtersB
ButtersB

Reputation: 514

Another angle to Manoj's submission ...

use a kwarg to pass user data, as to not mess with the method signature since it expects request.POST as the first argument. A better convention would be as follows.

class TrophiesForm(ModelForm):
    def __init__(self, *args, **kwargs):
        #using kwargs
        user = kwargs.pop('user', None)
        super(TrophiesForm, self).__init__(*args, **kwargs)
        self.fields['used_his'].queryset = User.objects.filter(pk = user.id)

Now in the call, this is more explicit and follows a better signature convention

form = TrophiesForm(request.POST, request.FILES, user=request.user)

You could also use instance: (note the super before you grab the instance obj)

class TrophiesForm(ModelForm):
    def __init__(self, *args, **kwargs):
        super(SubmissionUploadForm, self).__init__(*args, **kwargs)
        user = self.instance.user
        self.fields['used_his'].queryset = User.objects.filter(pk = user.id)

You can then call in your views.py like so:

form = TrophiesForm(instance=*MyModel*(user=request.user))

Upvotes: 10

Manoj Govindan
Manoj Govindan

Reputation: 74795

I think you can achieve this by overriding the __init__() method of the form, passing in an instance of User and filtering the queryset using that user. Something like this:

class TrophiesForm(ModelForm):
    used_his = forms.ModelMultipleChoiceField(queryset=Gun.objects.filter(user__id=1))

    def __init__(self, user, *args, **kwargs):
        super(TrophiesForm, self).__init__(*args, **kwargs)
        self.fields['used_his'].queryset = User.objects.filter(pk = user.id)

In your view you can pass in the appropriate (currently logged in) instance of User.

def my_trophies(request, *args, **kwargs):
    user = request.user
    form = TrophiesForm(user)
    ... 

Upvotes: 17

Related Questions