django 如何从.exclude(id=id)中获取id

zkure5ic  于 2023-03-04  发布在  Go
关注(0)|答案(1)|浏览(177)

学习Django的教程。在页面上“产品”是显示评级为这个产品。也有相关产品,我不能理解的逻辑来显示每个相关产品的评级。
product-detail.html

{% extends 'base.html' %}
{% load static %}
{% block content %}
<main class="container my-4">
    <h3 class="my-4 border-bottom pb-1">{{data.title}}</h3>
    <div class="row">
        <!-- Images -->
        <div class="col-md-4">
            <img id="zoom_01" data-zoom-image="/media/{{data.image}}" src="/media/{{data.image}}" class="card-img-top" alt="{{data.title}}">
        </div>
        <div class="col-md-8">
            <p>{{data.detail}}</p>
            <hr/>
            <table class="table table-bordered">
                <tr>
                    <h6>Цена</h6>
                    <h6>&#x20BD <span class="product-price-{{data.id}}">{{data.price}}</span></h6>
                </tr>
            </table>
            <hr/>
            <div class="input-group my-3" style="width:30%;">
              <input type="number" value="1" class="form-control product-qty-{{data.id}}" id="productQty" />
              <div class="input-group-append">
                  <input type="hidden" class="product-id-{{data.id}}" value="{{data.id}}" />
                  <input type="hidden" class="product-title-{{data.id}}" value="{{data.title}}" />
                  <input type="hidden" class="product-image-{{data.id}}" value="{{data.image}}" />
                <button class="btn btn-primary btn-sm add-to-cart" data-index="{{data.id}}" type="button" id="addToCartBtn"><i class="fa fa-shopping-cart"></i> В корзину</button>
              </div>
            </div>
        </div>
    </div>
    <hr />
    .....
            <!-- Reviews -->
            <div class="col-md-6">
                <h3 class="my-3">Reviews - <span class="avg-rating">{{avg_reviews.avg_rating}}</span>/5 <i class="fa fa-star text-warning"></i>
                    {% if user.is_authenticated %}
                    {% if canAdd %}
                    <button type="button" data-toggle="modal" data-target="#productReview" class="btn btn-warning bt-sm float-right reviewBtn">Add review</button>
                    {% endif %}
                    {% endif %}
                </h3>
                <div class="card">
                    <div class="card-body review-list" style="max-height: 400px; overflow; auto;">
                        <!-- Detail -->
                        {% if reviews %}
                            {% for review in reviews %}
                            <blockquote class="blockquote text-right">
                                <small>{{review.review_text}}</small>
                                    <footer class="blockquote-footer">{{review.user}}
                                        <cite title="Source Title">
                                            {% for star in review.review_rating|ljust:review.review_rating %}
                                            <i class="fa fa-star text-warning"></i>
                                            {% endfor %}
                                        </cite>
                                    </footer>
                            </blockquote>
                            <hr />
                            {% endfor %}
                        {% else %}
                            <p class="no-data">Add first review</p>
                        {% endif %}
                    </div>
                </div>
            </div>
    .....
        <!-- Related Products -->
        <h3 class="mt-4 mb-3 border-bottom pb-1">Related Products</h3>
        <div class="row">
            {% for product in related %}
            <div class="col-lg-3 col-sm-4 mb-4">
                <div class="card shadow">
                  <a href="/product/{{product.id}}"><img src="/media/{{product.image}}" class="card-img-top" alt="{{product.title}}"></a>
                  <div class="card-body">
                    <h6 class="card-text"><a href="/product/{{product.id}}">{{product.title}}</a></h6>
                  </div>
                  <div class="card-footer">
                    <button class="btn btn-sm btn-primary"><i class="fa fa-shopping-cart"></i></button>
                    <button class="btn btn-sm btn-danger"><i class="fa fa-heart"></i></button>
                    <span class="float-right">
                        4.5/5
                        <i class="fa fa-star text-warning"></i>
                    </span>
                  </div>
                </div>
            </div>
        {% endfor %}
        </div>
    </main>
    {% endblock %}

models.py

class Product(models.Model):
    title = models.CharField(max_length=30, null=True)
    detail = models.TextField(max_length=400, null=True)
    category = models.ForeignKey(Category, on_delete=models.CASCADE, null=True, blank=False)
    image = models.ImageField(upload_to="prod_imgs/", null=True)
    price = models.DecimalField(max_digits=7, decimal_places=2, null=True)
    status = models.BooleanField(default=True)
    is_featured = models.BooleanField(default=False)

    class Meta:
        verbose_name_plural = '02.Products'

    def image_tag(self):
        return mark_safe('<img src="%s" width="50" height="50" />' % (self.image.url))

    def __str__(self):
        return self.title

RATING=(
    (1,'1'),
    (2,'2'),
    (3,'3'),
    (4,'4'),
    (5,'5'),
)

class ProductReview(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    product = models.ForeignKey(Product, on_delete=models.CASCADE)
    review_text = models.TextField()
    review_rating = models.IntegerField(choices=RATING)

    class Meta:
        verbose_name_plural = '07. ProductReviews'

    def get_review_rating(self):
        return self.review_rating

views.py

def product_detail(request, id):
    product = Product.objects.get(id=id)
    related_products = Product.objects.filter(category=product.category).exclude(id=id)[:4]
    reviewForm = ReviewAdd()

    canAdd = True
    if request.user.is_authenticated:
        reviewCheck = ProductReview.objects.filter(user=request.user, product=product).count()
        if reviewCheck > 0:
            canAdd = False

    reviews = ProductReview.objects.filter(product=product)

    avg_reviews = ProductReview.objects.filter(product=product).aggregate(avg_rating=Avg('review_rating'))

    return render(request, 'product_detail.html', {'data': product, 'related': related_products, 'form': reviewForm, 'canAdd': canAdd, 'reviews': reviews, 'avg_reviews': avg_reviews})

    def save_review(request, pid):
        product = Product.objects.get(pk=pid)
        user = request.user
        review = ProductReview.objects.create(
            user=user,
            product=product,
            review_text=request.POST['review_text'],
            review_rating=request.POST['review_rating'],
        )
        data = {
            'user': user.username,
            'review_text': request.POST['review_text'],
            'review_rating': request.POST['review_rating'],
        }
    
        avg_reviews = ProductReview.objects.filter(product=product).aggregate(avg_rating=Avg('review_rating'))
    
        return JsonResponse({'bool': True, 'data': data, 'avg_reviews': avg_reviews})

<span class="avg-rating">{{avg_reviews.avg_rating}}</span>/5在这里不起作用。我知道对于相关产品,我只能从
related_products = Product.objects.filter(category=product.category).exclude(id=id),例如
related_avg_reviews = ProductReview.objects.filter(product=related_product).aggregate(avg_rating=Avg('review_rating'))
但我不知道该怎么做。

eqqqjvef

eqqqjvef1#

我没有看到你的模型,但是你需要把avg rating注解到你的related_products查询集。聚合为所有行生成avg。我认为它应该看起来像:

related_products = Product.objects\
                          .filter(category=product.category)\
                          .exclude(id=id)\
                          .annotate(avg_rating=Avg('productreview__review_rating')[:4]

这里我们使用反向的键关系将avg_rating注解到Product对象。在related_products的forloop中的模板中,您可以引用

{% for product in related %}
    {{ product.avg_rating }}
{% endfor %}

相关问题