【问题标题】:Django rendering a number as a 5-stars ratingDjango 将数字呈现为 5 星评级
【发布时间】:2020-04-22 22:06:56
【问题描述】:

我正在为我的网站建立一个评级系统。它目前运行良好,但我想改进系统的美学方面。我希望能够从数据库中获取评级并将其显示为 5 星评级。另外,如果不是太复杂,我希望能够点击星星将评分记录在数据库中,而不是写一个数字。

我对网络开发很陌生。特别是,我没有使用 javascript 的经验(我只做了在互联网上找到的教程),我认为这是实现我正在搜索的功能所必需的,所以请给我一个小例子和你的回复,以便让我能够理解。

为了将评分渲染为星星,我不知道该怎么做。为了将评分记录为星星,我想到了两种解决方案:

1) 使用django star-ratings,但我认为我不具备理解其工作原理所需的能力。我已经发帖寻求有关此应用程序的帮助和示例,但我没有收到任何帮助,所以我想我应该忘记这一点。

2) 使用带有一些适当小部件的表单将 IntegerInput 呈现为 5 星评级。

对于第二种解决方案,我已经有了代码,我现在需要一个小部件来替换下面代码中的'Stars',但我不知道该怎么做。有人能帮我吗 ?

models.py

class Avis(models.Model):
    note = models.IntegerField()

forms.py

class AvisForm(forms.ModelForm):
    class Meta:
        model = Avis
        fields = ['note']
        widgets = {'note': forms.NumberInput(attrs={'class': 'Stars'})}
        labels = {'note': 'Note /5'}

用于录制的hmtl

<form method="post" action="">
  {% csrf_token %}
  {% for field in form %}
  <div class="fieldWrapper form-group">
    {{ field.label_tag }}
    {{ field }}
  </div>
  {% endfor %}
  <input type="submit" class="btn btn-lg btn-outline-primary btn-block btn-login text-uppercase font- 
  weight-bold mb-2" value="Envoyer mon avis" />
</form>

hmtl 显示

{{ avis.note }}

提前致谢!

编辑(到目前为止,我的代码用于评级存储): 视图.py

def avis(request, id): # view for displaying and storing the form
    commande = get_object_or_404(Commande, id=id)

    if request.method == "POST":
        form = AvisForm(request.POST)
        if form.is_valid():
            avis = form.save(commit = False)
            avis.commande = commande
            avis.save()
            commande.has_avis = True
            commande.save()
            if commande.plat.chef.nb_avis==0:
                commande.plat.chef.rating = avis.note
            else:
                commande.plat.chef.rating = (commande.plat.chef.rating*commande.plat.chef.nb_avis + avis.note)/(commande.plat.chef.nb_avis + 1)
            commande.plat.chef.nb_avis += 1
            commande.plat.chef.save()
            messages.success(request, 'Votre avis a été correctement envoyé !')
            return redirect(mes_commandes)
    else:
        form = AvisForm()

    return render(request, 'actualites/avis.html', locals())

def avis2(request, id): # view for recording the rating
    avis = get_object_or_404(Avis, id=id)
    rating = request.POST.get('rating')
    avis.note = rating
    avis.save()
    messages.success(request, 'Votre avis a été correctement envoyé !')
    return redirect(mes_commandes)

html

 <form method="post" action="">
   {% csrf_token %}
   {% for field in form %}
   <div class="fieldWrapper form-group">
      {{ field.label_tag }}
      {{ field }}
   </div>
   {% endfor %}
   <input type="submit" class="btn btn-lg btn-outline-primary btn-block btn-login text-uppercase font-weight-bold mb-2" value="Envoyer mon avis" />
</form>
<div class="rating rating2">
  <a href="#5" title="Give 5 stars" data-value="5">★</a>
  <a href="#4" title="Give 4 stars" data-value="4">★</a>
  <a href="#3" title="Give 3 stars" data-value="3">★</a>
  <a href="#2" title="Give 2 stars" data-value="2">★</a>
  <a href="#1" title="Give 1 star" data-value="1">★</a>
</div>

<script>
  $(".rating a").on('click', function(e){
    let value = $(this).data('value');
     $.ajax({
        url: "{% url 'avis2' %}",
        type: 'POST',
        data: {'rating': value},
        success: function (d){
         // some processing
        }
     })
  });
</script>

forms.py

class AvisForm(forms.ModelForm):
    class Meta:
        model = Avis
        fields = ['commentaire']
        widgets = {'commentaire': forms.Textarea(attrs={'class': 'form-control'})}

【问题讨论】:

  • pypi 上的 django-star-ratings 上的文档有哪些不清楚的地方?
  • 没有示例,也没有关于如何实际使用该应用程序在模板中记录和显示评分的说明。也许我应该查看代码来理解,我做到了,但我对 Django 的理解还不够好。一位用户在下面给了我一个更简单的方法来做我想做的事,无论如何感谢您的评论
  • 你知道如何获取个人用户在django星级评分中的评分吗?

标签: django django-forms django-templates


【解决方案1】:

我将尝试回答您的两个问题。为了获得评分,您可以渲染星星并为其添加 JS 点击事件。 代码(HTML、CSS)来源:https://codepen.io/GeoffreyCrofte/pen/jEkBL

$(".rating a").on('click', function(e){
	let value = $(this).data('value');
   $.ajax({
      url: "some_url",
      type: 'POST',
      data: {'rating': value},
      success: function (d){
       // some processing
      }
   })
});
.rating {
  width: 300px;
  margin: 0 auto 1em;
  font-size: 45px;
  overflow:hidden;
}
.rating input {
  float: right;
  opacity: 0;
  position: absolute;
}
.rating a, 
.rating label {
			float:right;
			color: #aaa;
			text-decoration: none;
			-webkit-transition: color .4s;
			-moz-transition: color .4s;
			-o-transition: color .4s;
			transition: color .4s;
		}
.rating label:hover ~ label,
.rating input:focus ~ label,
.rating label:hover,
		.rating a:hover,
		.rating a:hover ~ a,
		.rating a:focus,
		.rating a:focus ~ a		{
			color: orange;
			cursor: pointer;
		}
		.rating2 {
			direction: rtl;
		}
		.rating2 a {
			float:none
		}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="rating rating2">
	<a href="#5" title="Give 5 stars" data-value="5">★</a>
	<a href="#4" title="Give 4 stars" data-value="4">★</a>
	<a href="#3" title="Give 3 stars" data-value="3">★</a>
	<a href="#2" title="Give 2 stars" data-value="2">★</a>
	<a href="#1" title="Give 1 star" data-value="1">★</a>
</div>

要渲染评分,您需要先计算值。您需要确定评分为 5、3、... 1 星的人数。假设有 100 个 5 星评级、70 * 4 星、50 * 3 星、30 * 2 和 20 * 1 星评级。因此,您可以通过以下方式确定评分:

评分总和/总评分

所以它将是 (100 * 5 + 70 * 4 + 50 * 3 + 30 * 2 + 20 * 1) / 100 + 70 + 50 + 30 + 20

所以最终评分将是:3.74

获取宽度百分比:(3.74 * 100) / 5 = 74.8

这里的5指的是总星数,这里我假设评分会基于5的等级。

为了呈现,您将需要不同的 HTML 和 CSS。

代码来源:https://codepen.io/Bluetidepro/pen/GkpEa

      .star-ratings-css {
            unicode-bidi: bidi-override;
            color: #c5c5c5;
            font-size: 25px;
            height: 25px;
            width: 100px;
            margin: 0 auto;
            position: relative;
            padding: 0;
            text-shadow: 0px 1px 0 #a2a2a2;
        }

        .star-ratings-css-top {
            color: #e7711b;
            padding: 0;
            position: absolute;
            z-index: 1;
            display: block;
            top: 0;
            left: 0;
            overflow: hidden;
        }

        .star-ratings-css-bottom {
            padding: 0;
            display: block;
            z-index: 0;
        }

        .star-ratings-sprite {
            background: url("https://s3-us-west-2.amazonaws.com/s.cdpn.io/2605/star-rating-sprite.png") repeat-x;
            font-size: 0;
            height: 21px;
            line-height: 0;
            overflow: hidden;
            text-indent: -999em;
            width: 110px;
            margin: 0 auto;
        }

        .star-ratings-sprite-rating {
            background: url("https://s3-us-west-2.amazonaws.com/s.cdpn.io/2605/star-rating-sprite.png") repeat-x;
            background-position: 0 100%;
            float: left;
            height: 21px;
            display: block;
        }
<div class="star-ratings-css">
    <div class="star-ratings-css-top" style="width: 74.8%">
        <span>★</span><span>★</span><span>★</span><span>★</span><span>★</span></div>
    <div class="star-ratings-css-bottom"><span>★</span><span>★</span><span>★</span><span>★</span><span>★</span></div>
</div>

您需要从视图和 HTML 中传递宽度,您需要访问它。 &lt;div class="star-ratings-css-top" style="width: {{ width }}%"&gt;。我尝试了这些代码 sn-p,为我工作,也应该为你工作:)

【讨论】:

  • 感谢您的大力帮助,非常感谢!对于渲染,它工作得几乎完美,但我无法将视图的宽度传递给模板。我在视图中定义宽度,将其传递给模板并使用style="width: {{ width }}%" 来获取它,但这并没有考虑宽度的值,并且始终显示 5 颗星。很奇怪,我对如何在 html 属性中使用变量进行了疯狂的研究,这应该可以工作
  • 对于记录,我不明白如何将值记录到我的数据库中。对不起,如果我是一个完整的菜鸟,但通常,我总是使用表单将对象记录到数据库中。在这里,我想我必须将代码的"// some processing" 部分替换为将我的avis 模型的属性note 更改为评级的东西。但是我不知道如何在 js 代码中访问模型的实例,因为该实例是在视图中使用表单中的值创建的。我可以请您帮忙吗?
  • 您从视图中提供的宽度是多少?并检查您的浏览器检查器。 // some processing 部分用于 Javascript,以防万一您想在事件成功时执行某些操作。您需要为 ajax 部分创建一个视图,您可以在其中创建新条目。
  • 我的观点只是def profil(request, id): chef = get_object_or_404(Chef, id=id) width = chef.rating*20 return render(request, 'inscription/profil_chef.html', locals()) 我也尝试过width = 80,但这也不起作用。在我的检查员中,它正确编写为width: 80%,所以我不明白为什么它显示 5 星而不是 4。我不明白你为 ajax 部分创建视图是什么意思,我已经有了这个功能的视图
  • 我的意思是存储喜欢的东西,如果它可以工作,那很好,但我不明白为什么宽度不适合你。你能检查一下你是否有任何 CSS 试图影响那个元素吗?
猜你喜欢
  • 2020-03-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-06-21
相关资源
最近更新 更多