I'm working on a medium sized project in django and i want to be able to access the current user from within my query manager. I need to be able to design a custom manager to limit the results and querysets so that the current user only get's information related to him/her.
I've received a few suggestions, I've also seen the not so supported example of using threadlocals from a django middleware. However, i'm very confused as this seems to be most promising solution now. I am looking for a better way to do this, so i can gain access to the current user from within a model manager.
you can store the user object in the session object and get it out when needed
refer to how-to-lookup-django-session-for-a-particular-user
There is no sane way to get the user outside of the request. If the current user matters then pass it to any functions that need it.
Related
I need to implement caching on my Django 1.8 site (to speed up rendering, obviously). Plan is to use Memcache, although this question isn't directly tied to it.
Right now, a lot of traffic goes to a specific set of blog posts that remain constant. But, there is a universal dynamic topbar across the whole site which can vary from logged-in user to logged-in user, so I need a cache function that kicks in if and only if the user is anonymous - e.g. one that is bypassed altogether if the user is logged in.
It looks like Django's builtin cache doesn't really distinguish between logged-in and logged-out users, so if I use it, there will be adverse effects for logged-in people.
I'll probably have to write my own cache decorator/cache function using the lower-level cache API and attach it to all of the logged-out-accessible URLs/views on the site. While it doesn't seem difficult, this does seem like an incredibly common feature. Is there really nothing in Django that does this properly already? I'm worried I might have missed something and am reimplementing the wheel.
Thank you!
First of all template caching is over rated. First use django debug toolbar to determine if template rendering is indeed slow on your django installation. I am betting that it's not the bottleneck. If you find that it's slow. YOu can cache on a per user basis as follows:
{% cache 300 FULL_PAGE request.build_absolute_uri request.user %}
The first parameter to the cache template tag is the timeout and the second one is the name others uniquely identify the fragment.
I saw the code in the accepted answer for this question:
How to access user names and profiles with django-allauth
But when I run a template with {{user.get_provider}}, nothing appears. I was expecting it to say either "LinkedIn Oauth2" or maybe "native". (Those are my two ways to log in.)
Are there special things you need to get the template calls working? Other template items are working fine, such as account.get_avatar_url.
To my knowledge the user profile doesn't record which credential was used to establish the current session, nor as far as I am aware does a list of a particular account's associated credential types automatically populate into the user context object (I'm not sure which you were trying to get from the question you asked).
You can access what credentials an account has available to it in python & export these to the context. See the socialaccount/connections.html template that comes with django-allauth as an example.
I'm trying to use Tornado with SqlAlchemy, I need to pass the current user from RequestHandler (tornado) to models (SqlAlchemy) in the insert or update action. But I don't want to pass the value directly to the model, example:
#### RequestHandler POST method...
user = Session.query(User).get(1)
user.name = "bla, bla, bla..."
user.updated_by = self.current_user # don't use...
session.commit()
I'm using a global variable, in a __ init__.py file, and set the current user value in the RequestHandler and after, get the value, in before update event with SqlAlchemy.
The idea is to know what user is the creator and updater.
Why I don't want pass the current user directly to model like the before example ?, because this will be a tool for other developers, and I'm trying to make comfortable for them, also, they can forget about it and it is important.
Is this a good idea, or maybe is there other better way ?
Your solution will have issues if you're handling more than one request at a time. Tornado is an async web framework so another request might overwrite your global var and set the user to someone else. It's good practice to store request depending data on self, tornado will make sure that data is altered by other simultaneous requests.
A solution that might work for you is to add your tool in the basic handler or create a decorator. It's tricky to sugest more details, please include more info in your question if you would like to get better alternatives.
The current user is available in every handler (and template). How you determine, authenticate and set the current user is up to you.
Basically just subclass tornado.web.RequestHandlerand override the get_current_user method in your new/own BaseHandler.
Here the quote from the tornado docs:
tornado User authentication
User authentication
The currently authenticated user is available in every request handler as self.current_user, and in every template as current_user. By default, current_user is None.
To implement user authentication in your application, you need to override the get_current_user() method in your request handlers to determine the current user based on, e.g., the value of a cookie. Here is an example that lets users log into the application simply by specifying a nickname, which is then saved in a cookie.
You can see a fully working example in the official tornado blog demo
I am in the midst of writing a web app in CherryPy. I have set it up so that it uses OpenID auth, and can successfully get user's ID/email address.
I would like to have it set so that whenever a page loads, it checks to see if the user is logged in, and if so displays some information about their login.
As I see it, the basic workflow should be like this:
Is there a userid stored in the current session? If so, we're golden.
If not, does the user have cookies with a userid and login token? If so, process them, invalidate the current token and assign a new one, and add the user information to the session. Once again, we're good.
If neither condition holds, display a "Login" link directing to my OpenID form.
Obviously, I could just include code (or a decorator) in every public page that would handle this. But that seems very... irritating.
I could also set up a default index method in each class, which would do this and then use a (page-by-page) helper method to display the rest of the content. But this seems like a nightmare when it comes to the occasional exposed method other than index.
So, my hope is this: is there a way in CherryPy to set some code to be run whenever a request is received? If so, I could use this to have it set up so that the current session always includes all the information I need.
Alternatively, is it safe to create a wrapper around the cherrypy.expose decorator, so that every exposed page also runs this code?
Or, failing either of those: I'm also open to suggestions of a different workflow. I haven't written this kind of system before, and am always open to advice.
Edit: I have included an answer below on how to accomplish what I want. However, if anybody has any workflow change suggestions, I would love the advice! Thanks all.
Nevermind, folks. Turns out that this isn't so bad to do; it is simply a matter of doing the following:
Write a function that does what I want.
Make the function in to a custom CherryPy Tool, set to the before_handler hook.
Enable that tool globally in my config.
I'm currently designing a Django based site. For simplicity lets assume that it is a simple community site where users can log in and write messages to other users.
My current choice is wether to use the buildin User-Model or to build something my own. I don't need much from the buildin User: there will be no username (you e-mail address is you username), but you an set an internal Name of your choice which can be used by multiple users (like Facebook). Additionally, I don't need the permission system, since access to others will not be based on groups. So I would end up using only the email, firstname, lastname and password fields from the buildin User and everything else would be placed in a UserProfile.
On the other hand, the buildin User system will come handy on the backend of the site, since there is the chance I will need a group based permission system there.
All in all, it looks to me, that I rather build my one User Model and use the buildin only for access to the admin backend.
Is there anything wrong with my reflections?
Is there anything wrong with my reflections?
Yes.
My current choice is wether to use the buildin User-Model or to build something my own.
There is a third choice.
http://docs.djangoproject.com/en/1.2/topics/auth/#storing-additional-information-about-users
everything else would be placed in a UserProfile
Correct.
build my one User Model and use the buildin only for access to the admin backend
Don't build your own.
Do this:
If you'd like to store additional
information related to your users,
Django provides a method to specify a
site-specific related model -- termed
a "user profile" -- for this purpose.
As the author of django-primate I would like to add some comments. Django-primate which easily lets ju modify the built in User model is meant for just that. You might need just something a little extra, then use django-primate.
But there are problems, although I do not think modifying the django User model per se is a problem at all. One problem is that the "users" are quite different, the admin user and some other user are often not related. This can cause problems when for example an admin is logged in and then wants to login to the site as a "normal user", they do not expect those accounts to be related and do not expect to be logged in automatically as the admin user. This causes headaches for no reason. It also causes a lot of other headaches to implement the recommended related Profile model, you often need to make sure there is a contrib user for every profile and a profile for every contrib user if you for example want to use the authentication decorators. Forms and administration of "users" make this even more cumbersome. In short: usually something will go wrong in this process at some point, it's a curse.
I have mostly abandoned the contrib User model for anything else but for admins. Building another user model is really what you want, but you also want the authenicating part for that user, hence the common use of django contrib User (using it for the wrong reasons). The best solution if you are in a situation like this is to build your own authenication for that custom user model. This is actually quite easy and I cannot recommend this approach enough. I think that the official recommendation is wrong and that there should instead be good tools for authenticating custom user models built into django.
You might want to have a look at the recently created django-primate: https://github.com/aino/django-primate
I once built a custom user model, inheriting from the default one. It works, however, I wouldn't recommend it.
Currently, you have some requirements, but over time they may change. Django's user system is quite straightforward, and using it allows to adapt more easily to some of the most common use cases.
Another aspect to think about, is that there are several applications already available that you can use, and that may require Django's users. Using your own model, may make usage of such modules much more difficult.
On the other hand, hacking the Django's user system in order to comply with your current requirements may be tricky.
Moreover, migrating a 'Custom-User' to a 'Django-User' is always possible, so you are not really closing that door.
Overall, I think it really depends on what you mean with 'user'.
If you mean just a registration, and no real interaction with the core Django features, then I think a separate model is enough, especially because you can migrate at any time, with relatively little effort.
However, if for your application a 'user' maps to something very similar to the what Django is for, then I would use the Django User-Model.