Получение среднего значения нескольких оценок из разных экземпляров модели (Django)
Я работаю над веб-приложением, которое позволяет менеджеру проекта оценивать поставщика после завершения задачи/работы. Вот содержимое models.py:
class Rating(models.Model):
RATE_CHOICES = [
(1, 'Below Expectation greater than 0.02'),
(2, 'Meet Expectaion 0.02'),
(3, 'Exceed Expectaions less than 0.02'),
]
reviewer = models.ForeignKey(CustomUser, related_name="evaluator",
on_delete=models.CASCADE, null=True, blank=True)
reviewee = models.ForeignKey(Vendor, null=True, blank=True,
related_name="evaluated_vendor", on_delete=models.CASCADE)
job = models.ForeignKey(Job, on_delete=models.CASCADE, null=True, blank=True,
related_name='jobrate')
date = models.DateTimeField(auto_now_add=True)
text = models.TextField(max_length=200, blank=True)
rate = models.PositiveSmallIntegerField(choices=RATE_CHOICES)
class Job(models.Model):
title = models.CharField(null=True, blank=True, max_length=100)
project_manager = models.ForeignKey(CustomUser, on_delete = models.CASCADE,
related_name="assigned_by")
startDate = models.DateField(blank=True, null=True)
deadlineDate = models.DateField(blank=True, null=True)
status = models.CharField(choices=STATUS, default='In Preparation', max_length=100)
evaluated = models.BooleanField(default=False)
#Related Fields
purchaseOrder = models.ForeignKey(PurchaseOrder, blank=True, null=True,
on_delete=models.CASCADE)
project = models.ForeignKey(Project, blank=True, null=True,
on_delete=models.CASCADE, related_name="Main_Project")
assigned_to = models.ForeignKey(Vendor, blank=True, null=True,
on_delete=models.CASCADE, related_name="Job_owner")
class Vendor(models.Model):
#Basic Fields.
vendorName = models.CharField(null=True, blank=True, max_length=200)
addressLine1 = models.CharField(null=True, blank=True, max_length=200)
country = models.CharField(blank=True, choices=COUNTRY_CHOICES, max_length=100)
postalCode = models.CharField(null=True, blank=True, max_length=10)
phoneNumber = models.CharField(null=True, blank=True, max_length=100)
emailAddress = models.CharField(null=True, blank=True, max_length=100)
taxNumber = models.CharField(null=True, blank=True, max_length=100)
mother_language = models.CharField(blank=True, choices=LANGUAGE_CHOICES,
max_length=300)
Вот мой view.py:
@login_required
def vendors(request):
context = {}
vendors = Vendor.objects.all()
context['vendors'] = vendors
if request.method == 'GET':
form = VendorForm()
context['form'] = form
return render(request, 'projects/vendors.html', context)
if request.method == 'POST':
form = VendorForm(request.POST, request.FILES)
if form.is_valid():
form.save()
messages.success(request, 'New Vendor Added')
return redirect('vendors')
else:
messages.error(request, 'Problem processing your request')
return redirect('vendors')
return render(request, 'projects/vendors.html', context)
Затем в моем HTML я хочу отобразить среднюю оценку нескольких работ, выполненных данным поставщиком, в колонке Average rate. Например, если поставщик выполнил 2 задания и получил оценки 1 и 2 соответственно. Средняя оценка для этого продавца будет равна 1,5. Я хочу, чтобы в таблице отображалась эта средняя ставка.
Вот мои текущие настройки в моем HTML:
<table class="table table-striped table-sm">
<thead>
<tr>
<th scope="col">Vendor Name</th>
<th scope="col">Mother Tongue</th>
<th scope="col"> Average Rating</th>
<th scope="col">Email Address</th>
<th scope="col">Phone Number</th>
<th scope="col">Address Line</th>
<th scope="col">Country</th>
</tr>
</thead>
<tbody>
{% for vendor in vendors %}
<tr>
<td>{{vendor.vendorName}}</td>
<td>{{vendor.mother_language}}</td>
<td>{{vendor.averagerating | stringformat:".2f"}}</td>
<td>{{vendor.emailAddress}}</td>
<td>{{vendor.phoneNumber}}</td>
<td>{{vendor.addressLine1}}</td>
<td>{{vendor.country}}</td>
</tr>
{% endfor %}
</tbody>
</table>
Вопрос в том, как я могу получить средний рейтинг данного продавца по всем работам, которые он/она выполнил и отобразить его в моей таблице списка продавцов. Обратите внимание, что колонка среднего рейтинга в настоящее время не отображается, она пуста. Ваш ответ будет оценен по достоинству. Заранее спасибо.
Обозначьте vendors
в вашем представлении средним значением связанных объектов рейтинга.
vendors = Vendor.objects.all().annotate(
averagerating=Avg("evaluated_vendor__rate"),
)
Смотрите этот раздел документации для подробностей о том, как это работает.
Относится к посту AKX: Вы также можете попробовать получить агрегацию из модели Rating следующим образом:
vendor_ranking = Rating.objects.filter(reviewee=vendor).aggregate(Avg("rate"))