bkbirr
December 16, 2020, 12:00am
1
I am attempting to run a celery async task from a view, but cannot figure out how to pass the logged in user to the task. Please help…
#views .py
class CallListView(LoginRequiredMixin, FormView, SingleTableView):
model = Call
table_class = CallTable
template_name = 'scraper/call_list.html'
form_class = CallForm
def get_success_url(self):
return reverse("calls")
def form_valid(self, form):
scrape_async.delay()
return super(CallListView, self).form_valid(form)
def get_queryset(self):
return Call.objects.filter(user=self.request.user)
#tasks .py
@shared_task
def scrape_async():
scrape(user)
return
I have figured out how to run the task on all users but I need it to only run on the logged in user.
Thanks!
You would need to pass the pk of the User to the task as a parameter, and then use it in the task.
bkbirr
December 16, 2020, 12:09am
3
I have tried adding request and self to:
def form_valid(self, form):
scrape_async.delay(self)
return super(CallListView, self).form_valid(form)
and
@shared_task
def scrape_async(self):
user = get_user_model().objects.get(user=self.request.user)
scrape(user)
return
with no luck. I have tried every variation of that I could think of and keep getting errors. Any tips on passing the pk? Thanks!
In the view, self
is not the user, self is the instance of the view.
How do you get the user from within the view? (Hint, see your get_queryset function.)
bkbirr
December 16, 2020, 12:17am
5
I have tried this:
def form_valid(self, form):
scrape_async.delay(user=self.request.user)
return super(CallListView, self).form_valid(form)
but am getting a Object of type User is not JSON serializable error
I have also tried:
def form_valid(self, form):
user = User.objects.get(user=self.request.user)
scrape_async.delay(user)
return super(CallListView, self).form_valid(form)
I am rerunning this now but forget the error I got from that.
Am I close?
You don’t need to pass the entire user object, just the pk of the User object (it’s the id
field if you’re not using a custom User object).
But, you already have the reference to the user object as self.request.user - there’s no need to query for it. You should be able to pass self.request.user_id directly as the parameter.
bkbirr
December 16, 2020, 12:25am
7
Something like this?
def form_valid(self, form):
scrape_async.delay(self.request.user_id)
return super(CallListView, self).form_valid(form)
bkbirr
December 16, 2020, 12:30am
9
and my task?
@shared_task
def scrape_async(user_id):
user = get_user_model().objects.filter(user=user_id)
scrape(user)
return
1 Like
Give it a try and see what happens!
2 Likes
bkbirr
December 16, 2020, 12:36am
11
With that I am getting a ‘ASGIRequest’ object has no attribute ‘user_id’ error.
bkbirr
December 16, 2020, 12:36am
12
I am using Django cookiecutter with its custom user model…
Try using self.request.user.id
bkbirr
December 16, 2020, 12:48am
14
I am pushing this to Heroku now to see if it runs:
#views .py
def form_valid(self, form):
user_id = self.request.user.id
scrape_async.delay(user_id)
return super(CallListView, self).form_valid(form)
#tasks .py
@shared_task
def scrape_async(user_id):
user = get_user_model().objects.get(id=user_id)
scrape(user)
return
bkbirr
December 16, 2020, 1:11am
16
This with the code below works! Thank you for your time and patience!