I have got tracks working with the extra() function. I do the
following:

tracks.extra(select={'owned':'SELECT Count(*) FROM shop_track_owners
WHERE track_id=shop_track.id and user_id='+str(user.id)})

This works great for tracks. However, how will I do this when I'm just
passing a queryset of albums or artists to a template? The template
uses

{% for track in album.track_set.all %}

which will get the tracks without the extra owned field added. Is
there a way around this? I don't think adding another function to the
model would do it because it can't get access to the user details so

{% for track in album.track_set_nice.all %}

where Album.track_set_nice adds the extra() bits wont work.

Is there a way of manipulating album in the view so that track_set
doesn't fire off a new query but accesses a pre-gathered set of
tracks? As far as I can tell it doesn't seem to like me adding my own
(non-database) variables to a method, so I don't *think* I can do
something like:

for album in albums:
    album.myTempTracks = album.track_set.extra(select={'owned':'SELECT
Count(*) FROM shop_track_owners WHERE track_id=shop_track.id and
user_id='+str(user.id)})

in the view. Does anyone know if there is a way to achieve this? I
tried but it didn't seem to work.

Any other suggestions would be much appreciated.

On Nov 13, 10:19 pm, Matt Schinckel <matt.schinc...@gmail.com> wrote:
> On Nov 14, 1:01 am, Chris <chrisbrett...@googlemail.com> wrote:
>
>
>
> > Thanks for your reply.
>
> > From reading around it sounds as though I am probably not meant to
> > solve this in the template (though this does seem like the easier
> > option).
>
> > I have figured out that I could solve this through an SQL statement as
> > follows:
>
> > select *, (select Count(*) FROM shop_track_owners where
> > track_id=shop_track.id and user_id=<<<insert current user id
> > here>>>)"owned" from shop_track;
>
> > I have run this and it works. There are two problems though:
>
> > 1: How do I do this through django querysets? I would like to keep the
> > database abstracted.
>
> You can execute arbitrary SQL like this using the extra method on aqueryset.  
> Something like:
>
> qs.extra(select={'count':'SELECT count(*) FROM shop_track_owners where
> track_id=shop_track.id and user_id=%i' % user.id)
>
>
>
>
>
> > 2: This will probably be rather awkward to do when talking about
> > artists or albums... Could I somehow modify the .track_set function of
> > the album model to not just return tracks (select * from shop_track)
> > but to run my other funky query?
>
> > Also I have had another thought: I could add an "owned" field to the
> > Track model. This could remain null for all tracks in the database
> > forever, but could be used in the view when grabbing the tracks to
> > pass the template whether or not each track is owned by the current
> > user. For example:
>
> > tracks = Track.objects.all()
> > for track in tracks:
> >     if request.user in track.owners:
> >         track.owned = True
>
> > Then render to response. Again, a couple of potential problems:
>
> > 1: Does altering the track object (track.owned = True) also alter the
> > object within tracks? I don't know if it a reference or a copy. If it
> > is a copy, is there any way of shoving it back in thequeryset?
>
> > 2: There is still the problem of what to do when talking about albums.
> > Could you do something like:
>
> > for album in albums:
> >     for track in album.track_set():
> >        if request.user in track.owners:
> >            track.owned = True
>
> > Again, would setting track.owned = True affect the track within the
> > album's track_set()? I would assume not... I think album.track_set()
> > executes a new database query to get the set, right? Is there any way
> > around this?
>
> > One last possibility that I can think of: is there any way of allowing
> > the track model to get at the request object? This would allow me to
> > write a method in the track model (owned) that checks if the track is
> > owned by the user in the request and then returns a bool.
>
> You can't always assume there is a request object: for instance any
> interaction with the system through ./manage.py shell doesn't have a
> request object.  Also, consider that there may be many request objects
> in the system at one time, if many users are using the system
> simultaneously.
>
> This is something that belongs in the view, and probably no lower, as
> that is the last place where there is _always_ a request object.
>
> Having said that, you could do something like this in the model:
>
> def owned(self, request):
>     "See if the user of this request owns this object"
>     return request.user in self.track_owners
>
> This then means you can call that method from anywhere, and pass in
> the current request object.
>
> > Thanks again.
>
> > On Nov 12, 8:12 pm, Tomasz Zieliñski
>
> > <tomasz.zielin...@pyconsultant.eu> wrote:
> > > On 12 Lis, 16:12, Chris <chrisbrett...@googlemail.com> wrote:
>
> > > > Is there a way of getting a model function to access user details so
> > > > that I can do a simple "if track.owned" in the template? Is there a
> > > > better solution to doing it in the view? Is there something I have not
> > > > thought of? What would be the "best practice" solution to this?
>
> > > Just some quick ideas (after 10h of work, so watch out ;)):
>
> > > 1. You can write custom tag {%ifowned track request.user%}
>
> > > 2. You can try something less elegant:
>
> > > {%for user in track.m2m_users.all%}
> > > {%ifequal user request.user%}
> > > <do what you want here>
> > > {%endifequal%}
> > > {%endfor%}
>
> > > - but it's only good for small apps, as a temp solution.
>
> > > --
> > > Tomasz Zieliñskihttp://pyconsultant.eu

--

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=.


Reply via email to