0

I have been struggling with a problem in Google App Engine and Django and have not been able to locate the solution (despite finding similar problems).

Let me set the scene a bit. I have the following three entities:

Contributor:
    user = db.UserProperty()

Question:
    contributor = db.ReferenceProperty(Contributor, collection_name='questions')
    text = db.TextProperty()

Rating:
    contributor = db.ReferenceProperty(Contributor, collection_name='question_ratings')
    question = db.ReferenceProperty(Question, collection_name='ratings')
    rating = db.IntegerProperty(choices=set([1,2,3,4,5]))

In my Django template (below), my general requirements are to display (1) each question, (2) the contributor of the question, and (3) whether or not a question has been rated by the current user.

My problem lies with the third requirement. I have not been able to figure out how to determine whether or not a Question has a Rating for the Contributor associated with current User (i.e., the Contributor with user property users.get_current_user()). How could I accomplish this?

If such a Rating entity exists, a message will be displayed similar to "You have already rated this question." Otherwise, if no such Rating exists, options to rate the question will be displayed. Here's my Django template for the first two requirements (and a comment outlining the third).

{% for question in questions %}
    <h1>{{ question.text }}</h1>
    <h2>{{ question.contributor.user.nickname() }}</h2>

    {% comment %}
    if no Rating exists for Question and Contributor:
        <h3>Rating: 1 2 3 4 5</h3>
    else:
        <h3>You have already rated this question.</h3>
    {% endcomment %}
{% endfor %}

Here's the Python handler script for Google App Engine:

questions = Question.all()

ratings = Rating.all()
ratings.filter('contributor = ', profile)

template_values = {
    'contributor': contributor,
    'questions': questions
}

path = os.path.join(os.path.dirname(__file__), "questions.html")
rendered_text = template.render(path, template_values)
self.response.out.write(rendered_text)
Community
  • 1
  • 1
mgub
  • 3
  • 1
  • 1

1 Answers1

0

The best way to do this is to do the processing in your Python code, and pass in a list of dicts that contain just the relevant information to your Django template. This also means you can take advantage of hacks like reference property prefetching to minimize the number of RPCs you have to do.

Nick Johnson
  • 100,655
  • 16
  • 128
  • 198
  • Thanks. I had thought about using this approach, but I thought there might be a better way. Is this really the best way? Could you suggest some resources that explain this further? – mgub Nov 24 '11 at 09:00
  • @mokogobo Yes, this is the best way - you should generally avoid processing, particularly anything that causes RPCs, in your template code. Django templates are explicitly structured to make this difficult, to discourage you from doing so. I'm not aware of any resources that deal with this specific issue. – Nick Johnson Nov 24 '11 at 21:40