【问题标题】:when i submit my form My Comment form dosen't save in database当我提交我的表单时,我的评论表单不会保存在数据库中
【发布时间】:2023-02-10 01:56:42
【问题描述】:

我使用 Django 和 Javascript 创建了一个 5 星评级系统,我想这样评论用户:

我想点击星星然后返回一个整数值

这是我的模型:

class Review(models.Model):
    course = models.ForeignKey(Product, on_delete=models.CASCADE, related_name='reviews')
    first_name = models.CharField(max_length=50)
    last_name = models.CharField(max_length=50)
    rating = models.IntegerField(null=True, validators=[MinValueValidator(1), MaxValueValidator(5)])
    comment = models.TextField()
    created = models.DateField(auto_now_add=True)
    active = models.BooleanField(default=False)
  
    def __str__(self):
        return f'{self.first_name} {self.last_name}

我的看法:

@csrf_exempt
def productDetailView(request, id, slug):
    product = get_object_or_404(Product, id=id, slug=slug, available=True)
    new_comment = None
    
    if request.method == 'POST':
        form = ReviewForm(request.POST)
        if form.is_valid():
            new_comment = form.save(commit=False)
            new_comment.course = product
            new_comment.rating = request.POST['rating']
            new_comment.save()
    else:
        form = ReviewForm()
    
    return render(request, 'shop/product_detail.html', {'product': product, 'form': form})

JS函数:

$(document).ready(function(){
        $('.rate .rate-item').on('click', function(){
            var value = $(this).data('value');
            $.ajax({
                url: '{{ product.get_absolute_url }}',
                type: 'POST',
                data: {'rating': value},
                success: function(response){
                    alert('Rating saved successfully!');
                }
            });
        });
    });

和我的模板:

<form method="post">
<div class="form-singel">
{{ form.first_name|attr:" placeholder:Fast name" }}
</div>
<div class="form-singel">
{{ form.first_name|attr:" placeholder:Last Name"}}
</div>
<div class="rate-label">Your Rating:</div>
<div class="rate">
<div data-value="1" class="rate-item"><i class="fa fa-star" aria-hidden="true"></i></div>
<div data-value="2" class="rate-item"><i class="fa fa-star" aria-hidden="true"></i></div>
<div data-value="3" class="rate-item"><i class="fa fa-star" aria-hidden="true"></i></div>
<div data-value="4" class="rate-item"><i class="fa fa-star" aria-hidden="true"></i></div>
<div data-value="5" class="rate-item"><i class="fa fa-star" aria-hidden="true"></i></div>
</form>
<div class="form-singel">
{{ form.first_name|attr:" placeholder:Comment" }}                                                                                               
</div>
<div class="form-singel">
<button type="submit" class="main-btn">Post Comment</button>
</div>

我如何解决它?

【问题讨论】:

    标签: javascript jquery django ajax django-forms


    【解决方案1】:

    您不需要 AJAX 单独发送评分值。相反,您可以使用 JavaScript 更新表单字段 rating 值(同时使用星形元素功能),并在准备就绪后提交:

    表单.py

    class ReviewForm(forms.ModelForm):
        class Meta:
            model = Review
            fields = ['first_name', 'last_name', 'comment', 'rating', 'course']
            labels = {
                'rating': '',
                'course': '',
            }
            widgets = {
                'rating': forms.HiddenInput(),
                'course': forms.HiddenInput(),
                'first_name': forms.TextInput(attrs={'placeholder': 'First Name'}),
                'last_name': forms.TextInput(attrs={'placeholder': 'Last Name'}),
                'comment': forms.Textarea(attrs={'placeholder': 'Comment'}),
            }
    

    视图.py

    def product_detail(request, id, slug=None):
        product = get_object_or_404(Product, id=id, available=True)
        
        if request.method == 'POST':
            form = ReviewForm(request.POST)
            if form.is_valid():
                form.save()
                messages.success(request, "Comment saved successfully")
                # Probably want to redirect somewhere else
                return redirect(reverse('core:product_detail', kwargs={'id': product.id}))
    
        else:
            form = ReviewForm(initial={'course': product})
        
        return render(request, 'shop/product_detail.html', {'product': product, 'form': form})
    

    一些注意事项:

    1. 好的做法是snake_case 中的函数和CamelCase 中的类。
    2. 您不需要两个字段来检索对象。要么去 idslug。由于您没有分享所有型号,我不确定是否 slug 也是独一无二的,所以我只是像往常一样使用 id
    3. 确保csrftoken出现在你的请求中,特别是当 修改数据库,这是一个安全问题。当然也是 可以use it with AJAX.

      商店/product_detail.html:

      <form method="POST" action="">
          {% csrf_token %}
          {% for field in form %}
              <div class="fieldWrapper">
                  {{ field.errors }}
                  <label for="{{ field_name.label_tag }}">{{ field.label_tag }}</label><br>
                  {{ field }}
              </div>
          {% endfor %}
          <div class="rate-label">Your Rating:</div>
          <div id="rate" style="display: flex; flex-flow: row nowrap;">
              <div data-value="1" class="rate-item"><i class="far fa-star" aria-hidden="true"></i></div>
              <div data-value="2" class="rate-item"><i class="far fa-star" aria-hidden="true"></i></div>
              <div data-value="3" class="rate-item"><i class="far fa-star" aria-hidden="true"></i></div>
              <div data-value="4" class="rate-item"><i class="far fa-star" aria-hidden="true"></i></div>
              <div data-value="5" class="rate-item"><i class="far fa-star" aria-hidden="true"></i></div>
          </div>
          <br>
          <input type="submit" value="Post Comment">
      </form>
      
      <script>
          const filledStarClass = 'fas fa-star';
          const emptyStarClass = 'far fa-star';
      
          $('.rate-item').on('click', function(){
              var value = $(this).data('value');
              updateStars(value);
              $('#id_rating').val(value)
          });
      
          function updateStars(value) {
              var childDivs = $('#rate').children();
              for( i=0; i< value; i++ ) {
                  var star = childDivs[i].children[0];
                  star.className = filledStarClass;
              }
      
              if (value < 5) {
                  for( i=value; i< childDivs.length; i++ ) {
                      var star = childDivs[i].children[0];
                      star.className = emptyStarClass;
                  }
              }
          }
      </script>
      

      在模板上,重点在$('#id_rating').val(value),我们根据star item data-value更新表单值。

    【讨论】:

      猜你喜欢
      • 2021-08-07
      • 1970-01-01
      • 1970-01-01
      • 2012-07-16
      • 2019-04-06
      • 2022-01-21
      • 2019-03-23
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多