Re: Question on passing user to model objects
Hi Daniel, > However, calling foo.bar_set multiple times does *not* get the same > queryset each time. Okay, that was new to me :-)... Do you know what the reason for that is? > I discuss this a little in a blog > entry > here:http://blog.roseman.org.uk/2010/01/11/django-patterns-part-2-efficien... Thanks! I thank that is exactly what I want to achieve. I changed _related_items to related_items (else Django would give me an error). The data should now be correct. I have a little problem passing the dict to the template though. When I did so, the template would have the keys - not the actual values. I also added: obj_arr=[] for key, obj in obj_dict.items(): obj_arr.append(obj) It's not very beautiful, but keeps the designer from using {% for key,value in dictionary.items %}{{ value }}{% endfor %} > Does this necessarily need to be a model method? Why not a custom > template tag or filter, that you can pass the request.user object to? Then the filter would have to be inserted everywhere where any of the object's attributes should be shown (the edit button is shown for each visible attribute). Thanks a lot! Stephan -- You received this message because you are subscribed to the Google Groups "Django users" group. To post to this group, send email to django-us...@googlegroups.com. To unsubscribe from this group, send email to django-users+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/django-users?hl=en.
Re: Question on passing user to model objects
> > isEditable=0 > > login=0 > > Assuming these two previous lines are at the top-level of you class > statement, both attributes will be class-attributes (that is "shared > by all instances"). I don't think this is what you want. Yes but that's what I intended. They should (and do) not all have the same value, but every instance of the object should have access to the user. Ideally I would have a static user class holding the current user (or global variable), but unfortunately I could not get that to work. > > def editable(self): > > if self.login==0: return False > > else: > > if self.isEditable!=0: return self.isEditable > > if self==self.login.get_profile(): > > Are you sure you want to compare the current whatever instance with a > profile ??? Nope, absolutly not :-). That should mean self.user instead of self. In the company self is right since it extends the user, but here I changed it. > > self.isEditable=True > > for o in self.offer_set.all(): o.editable=True > > Such a side-effect is really really bad practice (and, in this case, > mostly useless). I agree it's kind of bad. > > return True > > else: > > self.isEditable=False > > return False > > Code depending on the request.user should either takes an user as > param or live elsewhere. I will put it somewhere else. I guess you mean because the code is re- used twice. > > (I added the isEditable attribute to cache if the object is editable, > > since I wasn't sure if get_profile() is lazy loaded or sends a request > > to the db with each iteration) > > When you aren't sure, check, don't wildguess. Will do as soon as I am a little more used to Django. > > Yes that sounds possible. Just wondering if there is a cleaner way to > > do it - the ideal way would of course every object having access to > > the user in some way, but that seems impossible. > > Indeed. How would your code work in another environnment (command line > tool for example) else ? There it worked fine (the original version, as you stated this one had a bug). So it really must be the a different queryset. > wrt/ "a cleaner way to do it", your business rules are not clear > enough to come with a sensible answer. What I am trying to archive is rather simple - I just did not figure out a simple and clean way to do it: I have the company and offer objects. Each offer belongs to a company which belongs to a user. Whatever user is logged in should see an "edit" link on the live site, whenever his own company or offers come up. Anoynmous users should not see any edit links. -- You received this message because you are subscribed to the Google Groups "Django users" group. To post to this group, send email to django-us...@googlegroups.com. To unsubscribe from this group, send email to django-users+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/django-users?hl=en.
Re: Question on passing user to model objects
On Monday, December 13, 2010 11:20:21 AM UTC, Scoox wrote:Hi Daniel, thanks for your answer. Sorry, cmp should be c. I tried to only give the import parts to make it more readable, but I made a mistake there. The model code is pretty standard, except for one function: isEditable=0 login=0 def editable(self): if self.login==0: return False else: if self.isEditable!=0: return self.isEditable if self==self.login.get_profile(): self.isEditable=True for o in self.offer_set.all(): o.editable=True return True else: self.isEditable=False return False (I added the isEditable attribute to cache if the object is editable, since I wasn't sure if get_profile() is lazy loaded or sends a request to the db with each iteration) >> But the issue is likely to be that each call to foo_set.all() creates a >> brand new queryset fetched straight from the database. So doing >> something on the result of calling .all() in the view is irrelevant >> when you call .all again in the template. That's probably right. But from what I understood, all() is a lazy loader, so when Django loaded the objects once out of the db, it should not do that again when the same object is called in a template. Or did I understand that wrong? That's not quite right. Calling .all() on a queryset is indeed lazy, which means that it doesn't call the database until it's evaluated or iterated. Subsequent iterations *on the same queryset object* do not hit the database again. However, calling foo.bar_set multiple times does *not* get the same queryset each time. So, each one is a separate query, and changing attributes on the instances returned by one iteration does not have any effect on those returned by a second. I discuss this a little in a blog entry here: http://blog.roseman.org.uk/2010/01/11/django-patterns-part-2-efficient-reverse-lookups/ >> The best way to do this is probably to keep the queryset in a variable >> and send it explicitly to the template, then iterate through that Yes that sounds possible. Just wondering if there is a cleaner way to do it - the ideal way would of course every object having access to the user in some way, but that seems impossible. Does this necessarily need to be a model method? Why not a custom template tag or filter, that you can pass the request.user object to? -- DR. -- You received this message because you are subscribed to the Google Groups "Django users" group. To post to this group, send email to django-us...@googlegroups.com. To unsubscribe from this group, send email to django-users+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/django-users?hl=en.
Re: Question on passing user to model objects
On 13 déc, 12:20, Scoox wrote: > Hi Daniel, > thanks for your answer. Sorry, cmp should be c. I tried to only give > the import parts to make it more readable, but I made a mistake there. > The model code is pretty standard, except for one function: > > isEditable=0 > login=0 Assuming these two previous lines are at the top-level of you class statement, both attributes will be class-attributes (that is "shared by all instances"). I don't think this is what you want. > def editable(self): > if self.login==0: return False > else: > if self.isEditable!=0: return self.isEditable > if self==self.login.get_profile(): Are you sure you want to compare the current whatever instance with a profile ??? > self.isEditable=True > for o in self.offer_set.all(): o.editable=True Such a side-effect is really really bad practice (and, in this case, mostly useless). > return True > else: > self.isEditable=False > return False Code depending on the request.user should either takes an user as param or live elsewhere. > (I added the isEditable attribute to cache if the object is editable, > since I wasn't sure if get_profile() is lazy loaded or sends a request > to the db with each iteration) When you aren't sure, check, don't wildguess. > That's probably right. But from what I understood, all() is a lazy > loader, so when Django loaded the objects once out of the db, it > should not do that again when the same object is called in a template. > Or did I understand that wrong? You did. What "lazy" means here is that no request is issued until you start to iterate over the queryset or subscript it. > Yes that sounds possible. Just wondering if there is a cleaner way to > do it - the ideal way would of course every object having access to > the user in some way, but that seems impossible. Indeed. How would your code work in another environnment (command line tool for example) else ? wrt/ "a cleaner way to do it", your business rules are not clear enough to come with a sensible answer. -- You received this message because you are subscribed to the Google Groups "Django users" group. To post to this group, send email to django-us...@googlegroups.com. To unsubscribe from this group, send email to django-users+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/django-users?hl=en.
Re: Question on passing user to model objects
Hi Daniel, thanks for your answer. Sorry, cmp should be c. I tried to only give the import parts to make it more readable, but I made a mistake there. The model code is pretty standard, except for one function: isEditable=0 login=0 def editable(self): if self.login==0: return False else: if self.isEditable!=0: return self.isEditable if self==self.login.get_profile(): self.isEditable=True for o in self.offer_set.all(): o.editable=True return True else: self.isEditable=False return False (I added the isEditable attribute to cache if the object is editable, since I wasn't sure if get_profile() is lazy loaded or sends a request to the db with each iteration) >> But the issue is likely to be that each call to foo_set.all() creates a >> brand new queryset fetched straight from the database. So doing >> something on the result of calling .all() in the view is irrelevant >> when you call .all again in the template. That's probably right. But from what I understood, all() is a lazy loader, so when Django loaded the objects once out of the db, it should not do that again when the same object is called in a template. Or did I understand that wrong? >> The best way to do this is probably to keep the queryset in a variable >> and send it explicitly to the template, then iterate through that Yes that sounds possible. Just wondering if there is a cleaner way to do it - the ideal way would of course every object having access to the user in some way, but that seems impossible. Kind Regards Stephan -- You received this message because you are subscribed to the Google Groups "Django users" group. To post to this group, send email to django-us...@googlegroups.com. To unsubscribe from this group, send email to django-users+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/django-users?hl=en.
Re: Question on passing user to model objects
On Monday, December 13, 2010 10:22:32 AM UTC, Scoox wrote:Hi guys, I have a (probably easy) question. I need to pass the logged in user to my objects. I have the objects company and offer. I tried the following on the project's index / start view: c = Company.objects.all() cmp.login=request.user for j in cmp.offer_set.all(): j.company.login=request.user return render_to_response('show/startseite.html', {'company': c},context_instance=RequestContext(request)) This works fine for the company objects. However, it does *not* for the offer objects. For whatever reason, even though it should be available, the offer's user attribute is 0 (it's initial value). The template is like this (shortened to cover only import points): {% if company.editable %}(... user has edit rights - this works){%endif %} {% if company.offer_set.all %} {% for item in company.offer_set.all %} {% if journey.editable %} *** does not work *** Strange enough, when I display the vars: C: {{company.editable}} / OC: {{offer.company.editable}} / O: {{offer.editable}} I get C: true / OC: false / O: false So for whatever reason company does not seem to be the same as offer.company, although it is in the same loop. How could I solve this problem? Is there a suggested way to pass the logged in user to all objects? Kind Regards and thanks Stephan It's a bit hard to see what's going on, as you haven't provided your model definitions and your code seems to be incomplete (what is cmp?) But the issue is likely to be that each call to foo_set.all() creates a brand new queryset fetched straight from the database. So doing something on the result of calling .all() in the view is irrelevant when you call .all again in the template. The best way to do this is probably to keep the queryset in a variable and send it explicitly to the template, then iterate through that: offers = cmp.offer_set.all() for j in offers: whatever ... return render_to_response('show/startseite.html', {'company': c, 'offers': offers}, context_instance=RequestContext(request)) and in the template: {% for item in offers %} -- DR. -- You received this message because you are subscribed to the Google Groups "Django users" group. To post to this group, send email to django-us...@googlegroups.com. To unsubscribe from this group, send email to django-users+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/django-users?hl=en.
Question on passing user to model objects
Hi guys, I have a (probably easy) question. I need to pass the logged in user to my objects. I have the objects company and offer. I tried the following on the project's index / start view: c = Company.objects.all() cmp.login=request.user for j in cmp.offer_set.all(): j.company.login=request.user return render_to_response('show/startseite.html', {'company': c},context_instance=RequestContext(request)) This works fine for the company objects. However, it does *not* for the offer objects. For whatever reason, even though it should be available, the offer's user attribute is 0 (it's initial value). The template is like this (shortened to cover only import points): {% if company.editable %}(... user has edit rights - this works){%endif %} {% if company.offer_set.all %} {% for item in company.offer_set.all %} {% if journey.editable %} *** does not work *** Strange enough, when I display the vars: C: {{company.editable}} / OC: {{offer.company.editable}} / O: {{offer.editable}} I get C: true / OC: false / O: false So for whatever reason company does not seem to be the same as offer.company, although it is in the same loop. How could I solve this problem? Is there a suggested way to pass the logged in user to all objects? Kind Regards and thanks Stephan -- You received this message because you are subscribed to the Google Groups "Django users" group. To post to this group, send email to django-us...@googlegroups.com. To unsubscribe from this group, send email to django-users+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/django-users?hl=en.