I have a ‘ratings’ form which is used to submit ratings for an item. However, when the form is submitted, the rating will not appear in the admin area under ‘Ratings’. I have done some of my own debugged using print statements and discovered that it isn’t passing ‘if form.is_valid():’ statement, so im assuming the database isnt recieveing the data because of validation but other than that, I have struggled to get much further.
If I add a rating for an item through the form on the admin area, it will appear on the list of ratings on ratings.html.
I will show my ratings.html, forms.py, admin.py, my Rating class in models.py, and my ratings function in views.py below:
ratings.html
{% extends 'customer/base.html' %}
{% block content %}
<div class="container">
<div class="row justify-content-center mt-3">
<div class="col-md-6 col-sm-12 text-center">
<h1>Item Ratings</h1>
<h3>{{ item.name }}</h3>
</div>
</div>
<div class="row justify-content-center mt-5 mb-5">
<div class="col-md-8 col-sm-12 text-center">
<form method="GET" action="{% url 'ratings' item.id %}">
<div class="form-group">
<label for="name">Name:</label>
<input class="form-control" name="name" type="text" required>
</div>
<div class="form-group">
<label for="comment">Comment:</label>
<textarea class="form-control" name="comment" rows="4" required></textarea>
</div>
<div class="form-group">
<label for="rating">Rating:</label>
<select class="form-control" name="rating" required>
<option value="" disabled selected>Select rating</option>
<option value="5">5 - Excellent</option>
<option value="4">4 - Very Good</option>
<option value="3">3 - Good</option>
<option value="2">2 - Fair</option>
<option value="1">1 - Poor</option>
</select>
</div>
<button type="submit" class="btn btn-primary">Submit</button>
</form>
</div>
</div>
<div class="row justify-content-center mb-5">
{% if ratings %}
<div class="col-md-8 col-sm-12 text-center">
<h3>Reviews</h3>
<hr>
{% for rating in ratings %}
<div class="card mb-3">
<div class="card-body">
<h5 class="card-title">{{ rating.name }} - {{ rating.get_rating_display }}</h5>
<p class="card-text">{{ rating.comment }}</p>
</div>
</div>
{% endfor %}
</div>
{% endif %}
</div>
</div>
{% endblock content %}
forms.py:
from django import forms
from .models import Rating
class RatingForm(forms.ModelForm):
class Meta:
model = Rating
fields = ['name', 'comment', 'rating']
admin.py:
from django.contrib import admin
from .models import ShopItem, Category, OrderModel, Rating
admin.site.register(ShopItem)
admin.site.register(Category)
admin.site.register(OrderModel)
admin.site.register(Rating)
models.py:
class Rating(models.Model):
item = models.ForeignKey(ShopItem, on_delete=models.CASCADE, related_name='ratings')
name = models.CharField(max_length=100)
comment = models.TextField()
rating = models.PositiveSmallIntegerField(choices=(
(5, 'Excellent'),
(4, 'Very Good'),
(3, 'Good'),
(2, 'Fair'),
(1, 'Poor')
))
created_at = models.DateTimeField(auto_now_add=True)
def __str__(self):
return f'{self.item.name} ({self.rating}) by {self.name}'
views.py:
def ratings(request, item_id):
item = get_object_or_404(ShopItem, pk=item_id)
ratings = item.ratings.all().order_by('-created_at')
form = RatingForm()
if request.method == 'POST':
form = RatingForm(request.POST)
if form.is_valid():
rating = form.save(commit=False)
rating.item = item
rating.save()
return redirect(
reverse('ratings', args=[item.id])
)
context = {
'item': item,
'ratings': ratings,
'form': form
}
return render(request, 'customer/ratings.html', context)