Reputation: 1230
I need to display in a page a list with the candidates for their respective averages, the candidates' scores for the calculation of the average are in another model (Evaluation), this model receives an attribute score that contains the note of that evaluation that the candidate received and a foreign key with the candidate, so there may be several "Evaluation" with the same candidate, I have to display all the candidates with their respective averages, however the "Candidate" template does not have access to the notes, since they are stored in the Template "Evaluation", I then thought to make a for that would take the candidates of a queryset obj.all with the candidates and make the calculation of the average according to the current result, within a loop for in "Evaluation.objects.all ( ) ", Then after passing the candidate and his average to a dictionary that was placed in an array, so far so good, it works perfectly, however I need to make when clicking the candidate the user is to redirect (Name and other information) but to use "pk" I want queryset, not for certain dictionaries? So, what is my problem, I also tried queryset within the "Evaluation" template, but I can not access "Evaluation.objects.all ()" from within the "Evaluation" template itself to do the collection of 'score' and take the average, I really do not know what to do here, what do you suggest?
models.py
from django.db import models
from jsonfield import JSONField
from site_.settings import MEDIA_ROOT
from django.core.validators import MaxValueValidator
class Criterion(models.Model):
label = models.CharField(max_length=100)
def __str__(self):
return self.label
class Candidate(models.Model):
name = models.CharField(max_length=100)
e_mail = models.EmailField(max_length=100, default = '')
github = models.URLField(default = '')
linkedin = models.URLField(max_length=100, default = '')
cover_letter = models.TextField(default = '')
higher_education = models.BooleanField(default = False)
docfile = models.FileField(upload_to='/home/douglas/Documentos/Django/my-second-blog/site_/media', null=True, blank=True)
def __str__(self):
return self.name
class Evaluation(models.Model):
candidate = models.ForeignKey(Candidate)
criterion = models.ForeignKey(Criterion, default='')
score = models.PositiveIntegerField(default = 0, validators=[MaxValueValidator(10)])
appraiser = models.ForeignKey('auth.User')
def __str__(self):
return str(self.candidate)
#model de teste
class Teste(models.Model):
nome = models.CharField(max_length=10)
def __str__(self):
return str(self.nome)
views.py
from django.shortcuts import render, get_object_or_404
from .models import Candidate, Criterion, Evaluation
from django import forms
from .forms import CandForm
from .forms import EvalForm
from .forms import TestForm
from django.shortcuts import redirect
from django.db import IntegrityError
import re
def canditate_list(request):
candidates = Candidate.objects.all()
evaluation = Evaluation.objects.all()
context = {
'candidates': candidates,
'evaluation': evaluation,
}
return render(request, 'app/candidate_list.html',context)
def candidate_detail(request, pk):
candidate = get_object_or_404(Candidate, pk=pk)
c_name = candidate.name #pega o nome (string) do candidato
c1 = Evaluation.objects.all() #guarda tds Evaluation na variavel
scores = [] #declara a array que vai receber as notas
for c in c1:
cand = str(c.candidate) #guarda o nome do candidato do Evaluation atual
if cand == c_name: #confere se o Evaluation atual corresponde ao candidate atual(pk)
scores += [c.score]
soma = 0 #variavel que guardara a soma declarada
for s in scores:
soma += s #faz a soma dos scores
average = 0
if len(scores) > 0:
average = soma/len(scores) #tira a média
context = {
'candidate': candidate,
'average': average,
}
return render(request, 'app/candidate_detail.html', context)
html
{% load staticfiles %}
{% load mathfilters %}
<!DOCTYPE html>
<html>
<head>
<title>Lista de candidatos</title>
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css">
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap-theme.min.css">
<link href="https://fonts.googleapis.com/css?family=Lobster&subset=latin,latin-ext" rel="stylesheet" type="text/css">
<link href="{% static 'css/app.css' %}" rel="stylesheet">
</head>
<body>
<h1 class="h1t">Lista de Candidatos</h1>
{% for l in candidates %}
<p class="tr"><a href="{% url 'candidate_detail' l.pk %}">{{l}}</a></p>
{% endfor %}
</body>
</html>
Upvotes: 0
Views: 43
Reputation: 20339
You can do
from django.db.models import Avg
candidate = get_object_or_404(Candidate, pk=pk)
average = Evaluation.objects.filter(candidate= candidate).aggregate(Avg('score'))['score__avg']
Upvotes: 1