3

Is there a recommended way to pass a variable to all my views? Namely in my case, I want to pass a UserProfile object that Foreign Keys a django.contrib.auth.models.User object. I find most if not all my views need to pull the UserProfile object and putting it in Middleware seems like the way to go. It seems like I could do something like the following (I've seen a couple of solutions online that suggest it):

request.session['userprofile'] = userprofile_object

I don't like this because if my UserProfile model ever has a non-serializable field, it would break request.session.

2 Answers 2

6

If you have the AuthenticationMiddleware enabled, you will have a user object in all your views. To get the profile all you need to do is call user.get_profile in your view. For example, to output the id of the profile, you would do {{ user.get_profile.id }}.

If you would prefer not to call the get_profile function of the user object each time, you can add arbitrary items to your request. You would create a new middleware which would simply set

request.user_profile = request.user.get_profile()

Then just register that middleware in your settings.py and you should be good to go. I have used this method in the past for getting user geolocation data pinned to the request object.

Sign up to request clarification or add additional context in comments.

Comments

0

This proposal depends on the assumption that userprofile objects only matter when users are already logged in so you can get the logged in user via request.user. It should be possible to get the userprofile by travelling the foreignkey key relation in reverse like this:

if request.user.is_authenticated():
    request.user.userprofile_object_set.all() #gets all related userprofile objects
else:
   #...

3 Comments

Yeah, there are multiple ways to get the UserProfile object. You could also do UserProfile.objects.filter(user=request.user), but that doesn't answer the question, how do you pass it to a view?
Maybe I misunderstood your question then. Because every view gets request passed in as first argument, there would be no need to "pass" the profile into the view. If you want a variable with the userprofile available on every template, you could consider a custom context_processor which puts the userprofile_object into a variable.
I believe prof = request.user.userprofile_object_set.all()[0] will hit the database every time it's called?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.