tags:

views:

48

answers:

1

I'm trying to access an authenticated user within a form class. I played with passing the request object from a viewto the class init, but it seemed sloppy. Is there a better way to access the authenticated user or request object outside of a view?

class LicenseForm(forms.Form):
    '''def __init__(self, *args, **kwargs):
    #self.fields['license'] = forms.ModelChoiceField(queryset=self.license_queryset(), empty_label='None', widget=forms.RadioSelect())'''

    def license_queryset():
        queryset = License.objects.filter(organization__isnull=True)
        # add addtional filters if the logged in user belongs to an organization
        return queryset

    licenses = forms.ModelChoiceField(queryset=license_queryset(), empty_label='None', widget=forms.RadioSelect())
+1  A: 

Yes you can do it, here are instructions: http://code.djangoproject.com/wiki/CookBookThreadlocalsAndUser

Although this works I personally would prefer to pass the user to the form in the view. This feels less like a hack.

You could also show your code, maybe it can be improved. Why do you have to access the user in the form?

Update: You could do something like this:

class LicenseForm(forms.Form):
    def __init__(self, *args, **kwargs):
        super(LicenseForm, self).__init__(*args, **kwargs)
        self._user = kwargs.get('user',None)
        self.fields['licenses'] = forms.ModelChoiceField(queryset=self.license_queryset(), empty_label='None', widget=forms.RadioSelect())

    def license_queryset(self):
        queryset = License.objects.filter(organization__isnull=True)
        if self._user and self._user.belongsTo('SomeOrganization'):
            queryset  = queryset.filter(whatever='fits')
        return queryset

Imho this is a much cleaner approach as messing with local threads.

Felix Kling
I edited my original post to show the code I'm working with. So in the license_queryset method I want to add some additional filters depending on the authenticated users associations. The commented out __init__ is where I was going to accept the request object from the view.
CrashRoX
Your right, that does seem cleaner. I appreciate all the help. I played with that same code approach earlier but kept running into the issue of being able to access self within license_queryset. I had to create the licenses form field dynamically in init to get around it. Is there a way to make license_queryset have self scope and still be able to call it from the license form declaration? Sorry if these are newb questions. Just getting started with django and python :)
CrashRoX
@CrashRoX: You are right, I forgot on important point. Changed it. When you define class methods you always have to provide one parameter at least (called `self` for convenience). Later when you call that function you don't have to pass it, it is done automatically. This might help you to get into it: http://docs.python.org/tutorial/classes.html
Felix Kling
Dont think you can do that... You will get "license_queryset() takes exactly 1 argument". Then if you do self.license_queryset() you will get "name 'self' is not defined". Fun stuff!
CrashRoX
You are right, you can only set it in the `__init__` method. Sorry (it is just too late here ;)). But even that is cleaner than this thread thing imho.
Felix Kling
Thanks again. I will go the cleaner method.
CrashRoX