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 a
queryset.  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 the queryset?
>
> 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