I'm currently building a Django app that uses JavaScript and Ajax. One of the things I am doing is within each view, as well as outputting a variable as standard, I also JSON encode any objects on the page and return them as well, so when the page loads, they are in the DOM as values I can use to manipulate the page.
One of the issues I am having is with the code below for example:
def get_project_list(request): member = Member.members.get(user__exact = request.user) projects = [project for project in Project.projects.all() if project.get_permissions(request.user).view_project]
if request.is_ajax(): template = 'project/project_list_ajax.html' else: template = 'project/project_list.html'
When I go into the DOM tab in Firebug, I can see the variables in the dom. All are attached to a hgfront object, so for example, a page might look like this in the dom
+ hgfront + options + projects +0 +_project_manager_cache name id .....
As you can see, each object is converted into JSON, but the problem comes when I get a project, as you can see it passes along the _project_manager_cache - which is the user object. Now the problem I am having is the users password, although hashed, is showing like so:
The problem is that this isn't even being done with a select_related() query, so the object is automatically being output. What I want to know is there any way I could simplify the method and have it remove the password field any time a user object is being selected as part of a related query?? I'm sure there is a need for it when doing authorisation, but once a session has been confirmed, is it needed again?
On Sun, 2008-04-13 at 11:46 +0100, Tane Piper wrote:
[...]
> What I want to > know is there any way I could simplify the method and have it remove > the password field any time a user object is being selected as part of > a related query??
Not really, unless you use values(). For any model, if the Python object is being constructed, it pulls back all the values it needs to populate the attributes. The password hash is an attribute of the User model.
> I'm sure there is a need for it when doing > authorisation, but once a session has been confirmed, is it needed > again?
Login isn't the only time when the password hash might be needed (for example, it's displayed and editable in the admin screen) and it would be quite hacky to introduce a special case for saying when that field shouldn't be displayed. You're using the User object in public-readable situations, which isn't really part of the design. So change your design a bit so that you're not throwing around this information if you don't want it displayed. Yes, anything can be serialised using json, but that doesn't mean you should indiscriminately do so or that the framework should accommodate that.
It might make sense in your situation to just pull back the values() that you need for various objects and serialise that dictionary. Or you could make another pass through the projects list and blank out the attribute(s) you aren't interested in, such as _project_manager_cache.
values() seems to be the way to go for now. I've extracted some of the code back to a context variable, and anything within a view I'll just have to try and make it as efficient as possible, while still removing the user object from the context.
On Sun, Apr 13, 2008 at 11:59 AM, Malcolm Tredinnick
> On Sun, 2008-04-13 at 11:46 +0100, Tane Piper wrote: > [...]
> > What I want to > > know is there any way I could simplify the method and have it remove > > the password field any time a user object is being selected as part of > > a related query??
> Not really, unless you use values(). For any model, if the Python object > is being constructed, it pulls back all the values it needs to populate > the attributes. The password hash is an attribute of the User model.
> > I'm sure there is a need for it when doing > > authorisation, but once a session has been confirmed, is it needed > > again?
> Login isn't the only time when the password hash might be needed (for > example, it's displayed and editable in the admin screen) and it would > be quite hacky to introduce a special case for saying when that field > shouldn't be displayed. You're using the User object in public-readable > situations, which isn't really part of the design. So change your design > a bit so that you're not throwing around this information if you don't > want it displayed. Yes, anything can be serialised using json, but that > doesn't mean you should indiscriminately do so or that the framework > should accommodate that.
> It might make sense in your situation to just pull back the values() > that you need for various objects and serialise that dictionary. Or you > could make another pass through the projects list and blank out the > attribute(s) you aren't interested in, such as _project_manager_cache.
I seem to have come a cropper with this. Although it returns the fields I want on other models, on my Project model it seems to affect it's functions and attribues For example, in this line:
projects = [project for project in Project.projects.all() if project.get_permissions(request.user).view_project]
if I try do:
projects = [project for project in Project.projects.all().values('project_id', 'project_name') if project.get_permissions(request.user).view_project]
I get this error:
'dict' object has no attribute 'get_permissions'
I have tried passing it as a field but it comes back that it doesn't exist. Any suggestions?
<digitalspaghe...@googlemail.com> wrote: > Hi Malcolm,
> values() seems to be the way to go for now. I've extracted some of > the code back to a context variable, and anything within a view I'll > just have to try and make it as efficient as possible, while still > removing the user object from the context.
> On Sun, Apr 13, 2008 at 11:59 AM, Malcolm Tredinnick > <malc...@pointy-stick.com> wrote:
> > On Sun, 2008-04-13 at 11:46 +0100, Tane Piper wrote: > > [...]
> > > What I want to > > > know is there any way I could simplify the method and have it remove > > > the password field any time a user object is being selected as part of > > > a related query??
> > Not really, unless you use values(). For any model, if the Python object > > is being constructed, it pulls back all the values it needs to populate > > the attributes. The password hash is an attribute of the User model.
> > > I'm sure there is a need for it when doing > > > authorisation, but once a session has been confirmed, is it needed > > > again?
> > Login isn't the only time when the password hash might be needed (for > > example, it's displayed and editable in the admin screen) and it would > > be quite hacky to introduce a special case for saying when that field > > shouldn't be displayed. You're using the User object in public-readable > > situations, which isn't really part of the design. So change your design > > a bit so that you're not throwing around this information if you don't > > want it displayed. Yes, anything can be serialised using json, but that > > doesn't mean you should indiscriminately do so or that the framework > > should accommodate that.
> > It might make sense in your situation to just pull back the values() > > that you need for various objects and serialise that dictionary. Or you > > could make another pass through the projects list and blank out the > > attribute(s) you aren't interested in, such as _project_manager_cache.