Django 星级评分系统 AJAX 和 JavaScript
Posted
技术标签:
【中文标题】Django 星级评分系统 AJAX 和 JavaScript【英文标题】:Django star rating system AJAX and JavaScript 【发布时间】:2022-01-06 05:59:12 【问题描述】:我正在尝试在 Django 网站上实现星级评分系统。
我找到了以下,并喜欢这里的星星的风格:https://www.w3schools.com/howto/howto_css_star_rating.asp
目前对 javascript、AJAX 和 Django 了解有限。有谁知道如何结合 AJAX 和 Django 使用上述示例中的星星,以便在用户选择评分时无需刷新页面即可更新数据库(模型)?
同样重要的是,用户只能投票一次,即不允许他们对页面进行两次评分。为此,必须进行 IP 检查。我对代码感到困惑,需要帮助。
models.py
:
class Rating(models.Model):
ip = models.CharField(max_length=15)
post = models.ForeignKey(Post, related_name='ratings', on_delete=models.CASCADE)
score = models.IntegerField(default=0,
validators=[
MaxValueValidator(5),
MinValueValidator(0),
]
)
def __str__(self):
return str(self.pk)
views.py
:
def RatingView(request):
obj = Rating.objects.filter(score=0).order_by("?").first()
context =
'object': obj
return render(request, 'blog/post_detail.html', context)
# def get_client_ip(self, request):
# x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR')
# if x_forwarded_for:
# ip = x_forwarded_for.split(',')[0]
# else:
# ip = request.META.get('REMOTE_ADDR')
# return ip
def RateView(request):
if request.method == 'POST':
element_id = int(request.POST.get('element_id'))
val = request.POST.get('val')
print(val)
obj = Rating.objects.get(id=element_id)
obj.score = val
obj.save()
return JsonResponse('success':'true', 'score': val, safe=False)
return JsonResponse('success':'false')
urls.py
:
urlpatterns = [
path('rate/', views.RateView, name='rate'),
path('<slug:slug>/<slug:post_slug>/', views.PostDetailView.as_view(), name='detail'),
path('<slug:slug>/', views.CategoryView.as_view(), name='category'),
path('', views.HomeView.as_view(), name='home'),
]
html
:
<div class="col text-center">
<form class="rate-form" action="" method="POST" id=" object.id ">
% csrf_token %
<button type="submit" class="fa fa-star my-btn" id="first"></button>
<button type="submit" class="fa fa-star my-btn" id="second"></button>
<button type="submit" class="fa fa-star my-btn" id="third"></button>
<button type="submit" class="fa fa-star my-btn" id="fourth"></button>
<button type="submit" class="fa fa-star my-btn" id="fifth"></button>
</form>
<br>
<div id="confirm-box"></div>
</div>
JavaScript
:
// Stars
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')
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
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)=>
const val = event.target.id
console.log(val)
form.addEventListener('submit', e=>
e.preventDefault()
const id = e.target.id
console.log(id)
const val_num = getNumericValue(val)
$.ajax(
type: 'POST',
url: '/rate/',
data:
'csrfmiddlewaretoken': csrf[0].value,
'element_id': id,
'val': val_num,
,
success: function(response)
console.log(response)
confirmBox.innerHTML = `<p>Successfully rated with $response.score</p>`
,
error: function(error)
console.log(error)
confirmBox.innerHTML = '<p>Oops... Something went wrong...</p>'
)
)
))
这是错误本身:
4
Internal Server Error: /rate/
Traceback (most recent call last):
File "/home/kali/Django/personal_blog/venv/lib/python3.9/site-packages/django/core/handlers/exception.py", line 47, in inner
response = get_response(request)
File "/home/kali/Django/personal_blog/venv/lib/python3.9/site-packages/django/core/handlers/base.py", line 181, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/home/kali/Django/personal_blog/src/blog/views.py", line 91, in RateView
obj = Rating.objects.get(id=element_id)
File "/home/kali/Django/personal_blog/venv/lib/python3.9/site-packages/django/db/models/manager.py", line 85, in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
File "/home/kali/Django/personal_blog/venv/lib/python3.9/site-packages/django/db/models/query.py", line 435, in get
raise self.model.DoesNotExist(
blog.models.Rating.DoesNotExist: Rating matching query does not exist.
[29/Nov/2021 00:18:19] "POST /rate/ HTTP/1.1" 500 86956
对我来说,问题出在网址的某个地方。如何解决这个问题?
screenshot
【问题讨论】:
【参考方案1】:您的问题不在于网址,而在于查询obj = Rating.objects.get(id=element_id)
。没有 id=element_id 的评级对象。
要调试,请检查 Rating id 是否从 RatingView -> Template -> JS -> RateView 正确传递。
例如,在 RatingView 中,obj 可能是空的。
【讨论】:
即使在这里obj = Rating.objects.filter(score = 0).order_by("?").First()
也不正确。你能告诉我如何将评分与博客文章相关联吗?我需要将帖子上的信息发送到RatingView
以上是关于Django 星级评分系统 AJAX 和 JavaScript的主要内容,如果未能解决你的问题,请参考以下文章