1

The following code is working nicely:

class SelectTwoTeams(forms.Form):

    campaignnoquery = UserSelection.objects.filter(user=349).order_by('-campaignno')[:1]

    currentCampaignNo = campaignnoquery[0].campaignno

    cantSelectTeams = UserSelection.objects.filter(campaignno=currentCampaignNo)

    currentTeams = StraightredTeam.objects.filter(currentteam = 1).exclude(teamid__in=cantSelectTeams.values_list('teamselectionid', flat=True))
    team_one = forms.ModelChoiceField(queryset = currentTeams)
    team_two = forms.ModelChoiceField(queryset = currentTeams)

However, you can see that the user id is currently hardcoded into the filter as 349. I would like this to be the id of the user logged in. I know in the view I can use:

currentUser = request.user
currentUserID = currentUser.id

But this code does not work within the forms section. If anyone could point me in the correct direction that would be ideal.

When I follow the suggestion below using the following form I get an error saying: NameError: name 'currentUserID' is not defined

# coding=utf-8

from dwad.threadlocals import get_current_user

from django.db.models import Max
from django import forms
from straightred.models import StraightredTeam
from straightred.models import UserSelection



class SelectTwoTeams(forms.Form):

    def save(self):

        currentUser = get_current_user()
        currentUserID = currentUser.id

    campaignnoquery = UserSelection.objects.filter(user=currentUserID).order_by('-campaignno')[:1]
    currentCampaignNo = campaignnoquery[0].campaignno

    cantSelectTeams = UserSelection.objects.filter(campaignno=currentCampaignNo)

    currentTeams = StraightredTeam.objects.filter(currentteam = 1).exclude(teamid__in=cantSelectTeams.values_list('teamselectionid', flat=True))
    team_one = forms.ModelChoiceField(queryset = currentTeams)
    team_two = forms.ModelChoiceField(queryset = currentTeams)

Many thanks, Alan.

Alan Tingey
  • 835
  • 11
  • 39

2 Answers2

1

One method is to use local.threading. I have used this solution on a number of Django installations to good use.

I know there are a number of different opinions whether this is a good or bad solution. I tend to fall into the category that it can be extremely good in the right circumstances.

To set it up, create a file called threadlocals.py:

try:
    from threading import local
except ImportError:
    from django.utils._threading_local import local

_thread_locals = local()

def get_current_user():
    return getattr(_thread_locals, 'user', None)

class ThreadLocalsMiddleware(object):
    def process_request(self, request):
        _thread_locals.user = getattr(request, 'user', None)

Then, add this ThreadLocalsMiddleware class to your project's middleware in settings.py:

MIDDLEWARE_CLASSES = [
    ...
    'myproject.threadlocals.ThreadLocalsMiddleware',
    ...
]

Now, all you need to do is call the method get_current_user() from anywhere in your project.

from myproject.threadlocals import get_current_user


class SelectTwoTeams(forms.Form):
    def save(self):
        # for example:
        currentUser = get_current_user()
        currentUserID = currentUser.id
Community
  • 1
  • 1
Adam Hopkins
  • 6,837
  • 6
  • 32
  • 52
  • That looks great. I just need to pop out so will try in a few hours. Thank you. – Alan Tingey Aug 28 '16 at 16:39
  • ;-) Will be standing by if you need any help getting it running. – Adam Hopkins Aug 28 '16 at 16:44
  • You are a gentleman. On way home so hope to be on it within the hour. – Alan Tingey Aug 28 '16 at 18:51
  • I seem to be getting the following error: currentUserID = currentUser.id AttributeError: 'NoneType' object has no attribute 'id'. I thought I would check to see what is happening with the variable currentUser so changed currentUserID = currentUser and it just returned "none". Any thought sir? – Alan Tingey Aug 28 '16 at 19:58
  • Hmm, perhaps the positioning of the ThreadLocalsMiddleware in your middleware list? In situations like this, I usually try to incrementally step up my execution chain and put a raise Exception(...) just to see that the variables are set at the right place. Perhaps a first place is inside the process_request to see that getattr(request, 'user', None) is returning the user you expect. – Adam Hopkins Aug 28 '16 at 20:20
  • I put the "'myproject.threadlocals.ThreadLocalsMiddleware'," as the last in the list and that seems to work. Many thanks for that. Just because I am curious do you know why that would be the case? – Alan Tingey Aug 28 '16 at 20:52
  • next issue :( When i put the line "def save(self):" in the form the fields stop working in the form? If I remove it I get the following error: AttributeError: 'NoneType' object has no attribute 'id'. Sorry for being a pain. – Alan Tingey Aug 28 '16 at 21:11
  • I will add to the question as now I have done this part I get two different errors depending on where my indents are :/ driving me insane. Seems something that should be used so often yet is ever so fiddly :/ sorry – Alan Tingey Aug 28 '16 at 21:28
  • (1) Would you kindly accept the answer as being correct? (2) I think the ThreadLocalsMiddleware should be fine as long as you are after 'django.contrib.sessions.middleware.SessionMiddleware'. I could be wrong, I am just thinking off the top of my head without checking. In short, it needs to be after the request object is populated with the user information. (3) What is it that you ultimately want to do with that user ID? Might be helpful before trying to figure out where to put that code. – Adam Hopkins Aug 28 '16 at 21:58
  • 1) I can't click accept as the solution does not actually solve the problem. I still cant put the user.id in the query within the form :/ Whatever I do it just does not allow me to use it where i need it. I can use it in the view but not in the form. The imports etc are the same in both. 2) Understood. 3) All along I have wanted to use it as part of a query on a film to create a drop down list. – Alan Tingey Aug 28 '16 at 22:04
  • If it is easier I can click accept or close the question and put a new question as to what the current issue is? – Alan Tingey Aug 28 '16 at 22:05
  • I think you should put a new question as its a slightly different question. If you post that comment here, I'll take a look tomorrow. – Adam Hopkins Aug 28 '16 at 22:30
  • Not a problem. Think I need sleep so will post the question tomorrow. Thanks for your help. – Alan Tingey Aug 28 '16 at 22:34
  • Look forward to helping you some the riddle. – Adam Hopkins Aug 28 '16 at 22:40
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/122104/discussion-between-the-brewmaster-and-alan-tingey). – Adam Hopkins Aug 29 '16 at 12:29
0

Found this answer at Reddit. It is very simple and it is working good in my case. In your view you have to include some code like this:

if form.is_valid():
obj = form.save(commit=False)
obj.user = request.user # logged in user is available on a view func's `request` instance
obj.save() # safe to save w/ user in tow
George
  • 1
  • 2