views:

82

answers:

2

Hello, I am making some view functions to calculate the rank of one user in a community. My problem is that i want to display the rank afferent to each user, in its profile, and i don't know how, since i don;t have a request and a render_to_response (cause i guessed they are not needed) my code:

def calculate_questions_vote(request):
    useranswer = Answer.objects.filter (answer_by = request.user)
    positive_votes = VoteUpAnswer.objects.filter(answer = useranswer)
    negative_votes = VoteDownAnswer.objects.filter(answer = useranswer)
    question_vote_rank = sum(positive_votes) - sum(negative_votes.count)
        return question_vote_rank

def calculate_replies(request):
    the_new = News.objects.filter(created_by = request.user)
    reply = Reply.objects.filter(reply_to = the_new)
    reply_rank = sum(reply)
        return reply_rank

def calculate_votes(request):
    the_new = News.objects.filter(created_by = request.user)
    vote = Vote.objects.filter(voted = the_new)
    vote_rank = sum(vote)
        return vote_rank

def personal_rank(request):
    personal_rank = question_vote_rank + reply_rank + vote_rank
        return personal_rank

and in UserProfiles:

user = request.user  
personal_rank = calculate_questions_vote(user) + calculate_replies(user) + personal_rank(user)

but my error is:

Error binding parameter 0 - probably unsupported type.

Is mt approach correct? How should i call the rank function in the profile_view def ?

Thanks!

+4  A: 

YOu can call the function in your view like rank = personal_rank(reuest.user) and add rank to your context then.
I wouldnt call this functions "view"-functions, since they are not dealing with a request nor are they returning a HttoResponce; they are more "helper" functions and also don't belong to a model if they are dealing with seperate entities (eg. News & Vote). A descent place for them would be eg. utils.py. You import them from there in your views.py and call them with the user as parameter (if it's the actual user it's request.user).
It makes sense that you can't access request from everywhere, because this forces you to keep more to a mvc-like design, if you need request somewhere you need to pass it on from your original view function! You should change your last function to:

def personal_rank(user):
    personal_rank = calculate_questions_vote(user) + \
                    calculate_replies(user) + \
                    calculate_votes(user)
    return personl_rank

You could also add this last function to your User or UserProfile model class if you have something like that and then call eg. my_user.personal_rank() or my_user.get_profile().personal_rank().

lazerscience
+1 for adding these functions to the UserProfile class.
Daniel Roseman
thanks so much for help!
dana
question: if i add the personal_rank function to userProfiles as described, and return the variable as described (not in a context), if i call it in the template afferent to userProfile, it shows me nothing... how can i make the userProfile template aware of my variable personal_rank?Thanks!
dana
You can put it in your UserProfile class like that: def personal_rank(self): user = self.user personal_rank = calculate_questions_vote(user) + \ calculate_replies(user) + \ calculate_votes(user) return personl_rank(if your relation between user profile and user is called "user")Make sure to import the other functions from the place where they are defined or put them in the same class following this scheme!
lazerscience
if i return just personal_rank, (with no render_to_response or smth like that) how can the template 'know' the variable personal_rank ? i tryies, but the variable "personal_rank" is just an empty string..
dana
can you post me the view?
lazerscience
I've edited adding the view function you told me about. should i put the entire content of the views.py? (it is quite long).thanks!
dana
you need to add the result to the context, eg: return render_to_response('profile/publicProfile.html', { 'u':u, 'cv':cv, 'blog':blog, 'personal_rank': user.personal_rank() }, context_instance=RequestContext(request))or if you have `user` already in the context you can call it in the template `{{ user.personal_rank }}`.
lazerscience
if i put the definition of personal_rank in the accounts view, and then i return the personal_rank in the view function that points to the template where i want the rank variable to be displayed, i gen an error like:'unicode' object has no attribute 'personal_rank' ().if i return the variable rank in the function personal_rank edited below, and pointing to the same template(the one i want the rank in) is still empty string:D
dana
+3  A: 

lazerscience gave good explanation for your guestion. I just want to point some possible performance issues.

Please note that calling this method for each User yields with 7 queries. If your case will be showing rank for all users it might take a lot of time. I suggest make some caching (like in StackOverflow). There are many options here, for example you can assign special rank field to a User model (or UserProfile if User is auth.User) in which you could store precalaculated rank (calculated just after some operation, like News saving or in some scheduled intervals).

Lukasz Dziedzia