Reputation: 2402
Assume these as django models:
class Question():
question = charfield()
choice = charfield(choices = answer_choice)
class Answer():
question = models.foreignkey(Question, related_name = 'answers')
answerer = models.foreignkey('auth.User')
answer = models.charfield()
I'm building a page where i display 100 questions, and each User
can answer, but cannot change the answer for each question. For each question, i have to check whether the User
already exists or not on Answerer
. Then i make templatetags:
@register.filter
def this_user_exists(user,obj):
obj = obj.answers.filter(answerer_id = user.id)
return obj
Then on the template:
# obj is list of question
{% if not user|this_user_exists:obj %}
# can answer
{% else %}
# cannot answer
{% endif %}
The problem is, for every question, it generate 1 query, so for 100 question it'll generate 100 query. I tried this query to generate question Question.objects.all()
and Question.objects.prefetch_related('answers')
, still got the problem. Is there a better way to achieve this without making too many query?
Upvotes: 0
Views: 162
Reputation: 12318
In your view:
answered_ids = [ans.question_id for ans in Answer.objects.filter(answerer=request.user)]
In your template:
{% if not obj.id in answered_ids %}
# can answer
{% else %}
# cannot answer
{% endif %}
Upvotes: 0
Reputation: 4467
To reduce queries, you can first query out your needed answers, and then fetch all related answerers,
answers = Answer.objects.select_related('answerer').filter(xxxx)
# fetch related user id's
userids_in_answer = [answer.answerer.id for answer in answers]
# fetch user ids
user_id_set = set(User.objects.filter(id__in=userids_in_answer).values('id', flat=True)
after that, you can easily know whether user exists by,
for answer in answers:
if answer.answerer.id in user_id_set:
xxx
The query num is reduced, you can check whether this helps.
Upvotes: 2