django - 我为用户在 django 中为送货员实施了星级评分系统,但我被困在如何计算平均值上
问题描述
我有一个模型名称 Ratings 并通过外键关系连接到自定义用户模型。我使用 javascript 发布数据并通过使用 id 的 get 方法在后端获取评级但问题是评级过程工作正常但它只是升级当前查询集曾经被视为送货员得到评级。那么我如何计算平均值,因为它不存储以前的查询集,而只是升级该特定送货员的查询集
视图.py
def rate_user(request):
if request.method == 'POST':
el_id = request.POST.get('el_id')
val = request.POST.get('val')
print(val)
obj = Ratings.objects.get(id=el_id)
obj.rated_number = val
obj.save()
return JsonResponse({'success':'true', 'score': val}, safe=False)
return JsonResponse({'success':'false'})
模型.py
class Ratings(models.Model):
rated_user = models.ForeignKey(User,on_delete=models.CASCADE,blank=True,null=True)
avg_rating = models.CharField(max_length=5,null=True,blank=True,default=0)
# count = models.CharField(max_length=100000,blank=True,null=True,default=0)
rated_number = models.IntegerField(blank=True,null=True,default=0,
validators = [
MaxValueValidator(5),
MinValueValidator(1),
]
)
def __str__(self):
return str(self.pk)
@receiver(post_save, sender=User)
def create_ratings(sender, instance, created, **kwargs):
if created:
if instance.is_delivery_man or instance.is_driver:
Ratings.objects.create(rated_user=instance)
js
<script>
const one = document.getElementById('first')
const two = document.getElementById('second')
const three = document.getElementById('third')
const four = document.getElementById('fourth')
const five = document.getElementById('fifth')
// get the form, confirm-box and csrf token
const form = document.querySelector('.rate-form')
const confirmBox = document.getElementById('confirm-box')
const csrf = document.getElementsByName('csrfmiddlewaretoken')
const handleStarSelect = (size) => {
const children = form.children
console.log(children[0])
for (let i = 0; i < children.length; i++) {
if (i <= size) {
children[i].classList.add('checked')
} else {
children[i].classList.remove('checked')
}
}
}
const handleSelect = (selection) => {
switch (selection) {
case 'first': {
handleStarSelect(1)
return
}
case 'second': {
handleStarSelect(2)
return
}
case 'third': {
handleStarSelect(3)
return
}
case 'fourth': {
handleStarSelect(4)
return
}
case 'fifth': {
handleStarSelect(5)
return
}
default: {
handleStarSelect(0)
}
}
}
const getNumericValue = (stringValue) => {
let numericValue;
if (stringValue === 'first') {
numericValue = 1
}
else if (stringValue === 'second') {
numericValue = 2
}
else if (stringValue === 'third') {
numericValue = 3
}
else if (stringValue === 'fourth') {
numericValue = 4
}
else if (stringValue === 'fifth') {
numericValue = 5
}
else {
numericValue = 0
}
return numericValue
}
if (one) {
const arr = [one, two, three, four, five]
arr.forEach(item => item.addEventListener('mouseover', (event) => {
handleSelect(event.target.id)
}))
arr.forEach(item => item.addEventListener('click', (event) => {
// value of the rating not numeric
const val = event.target.id
let isSubmit = false
form.addEventListener('submit', e => {
e.preventDefault()
if (isSubmit) {
return
}
isSubmit = true
// rate id
const id = e.target.id
// value of the rating translated into numeric
const val_num = getNumericValue(val)
$.ajax({
type: 'POST',
url: '/rate/',
data: {
'csrfmiddlewaretoken': csrf[0].value,
'el_id': id,
'val': val_num,
},
success: function (response) {
console.log(response)
confirmBox.innerHTML = `<h1>Successfully rated with ${response.score} star</h1>`
},
error: function (error) {
console.log(error)
confirmBox.innerHTML = '<h1>Ups... something went wrong</h1>'
}
})
})
}))
}
</script>
形式
{%for i in ratings%}
<a href="#" >Average Ratings: {{i.rated_number}}</a><br><br>
i class="fas fa-vote-yea"></i> Rate this user <br>
<form class="rate-form" action="" method="POST" id={{i.id}}>
{% csrf_token %}
<button type="submit" class="fa fa-star fa-3x my-btn" id="first"></button>
<button type="submit" class="fa fa-star fa-3x my-btn" id="second"></button>
<button type="submit" class="fa fa-star fa-3x my-btn" id="third"></button>
<button type="submit" class="fa fa-star fa-3x my-btn" id="fourth"></button>
<button type="submit" class="fa fa-star fa-3x my-btn" id="fifth"></button>
</form>
{%endfor%}
<br>
<div id="confirm-box"></div>
</div>
解决方案
最后等待stackoverflow的答案我累了,开始调试自己,我最终得到了一个很好的数学算法来实现我想要的目标,我认为我已经实现了它,除了它不显示或取小数点后的值。avg 带有圆形。
我只是在我的模型中更改了一个字段来存储以前和现在所有的评级号码添加
class Ratings(models.Model):
rated_user = models.ForeignKey(User,on_delete=models.CASCADE,blank=True,null=True)
storing_prev_now_rated_value = models.IntegerField(null=True,blank=True,default=1)
avg_rating = models.IntegerField(null=True,blank=True,default=1)
count = models.IntegerField(blank=True,null=True)
rated_number = models.IntegerField(blank=True,null=True,default=1,
validators = [
MaxValueValidator(5),
MinValueValidator(1),
]
)
def __str__(self):
return self.rated_user.username
我的views.py也有变化
def rate_user(request):
if request.method == 'POST':
el_id = request.POST.get('el_id')
val = request.POST.get('val')
print(val)
obj = Ratings.objects.get(id=el_id)
storing_prev_rated_number = obj.rated_number
obj.rated_number = val
obj.count = obj.count + 1
store_count = obj.count
old_addition_values = obj.storing_prev_now_rated_value
obj.storing_prev_now_rated_value = int(old_addition_values) + int(val)
store_storing_prev_now_rated_value = obj.storing_prev_now_rated_value
print(store_storing_prev_now_rated_value)
obj.avg_rating = float(store_storing_prev_now_rated_value // store_count)
j = obj.avg_rating
print(j)
obj.save()
return JsonResponse({'success':'true', 'rated_number': val}, safe=False)
return JsonResponse({'success':'false'})
推荐阅读
- javascript - “RectAreaLightHelper”在 React-three-fiber 中不动
- node.js - Cookie 不会保存在浏览器中
- mqtt - 通过 mqtt 从设备更新 IOT Central 中的可写属性
- istio - istio 如何进行基于权重的 tcp 流量转移?
- vba - Word-VBA-为什么我在内容控件中输入值后占位符文本会发生变化?
- c++ - 谁能向我解释默认参数值如何在 C++ 的递归函数中工作?
- javascript - 将 C# 位运算转换为 Javascript
- rust - 让 GtkComboBox 条目为 Pixbuf 或 String
- python - 为什么 os.system('cls') 不清除最近的输出?
- swift - 如何以高性能的方式将可变数组用作字典值?