Django: filter a model with a field from another model

浪子不回头ぞ 提交于 2021-02-11 17:47:41

问题


This is my first Django app. I am trying to display an average rating from multiple reviews.

This seems to work in my product template but not on my blog template because productprofile_id is not defined:

product_rating = Review.objects.filter(product_id=productprofile_id).aggregate(Avg('rating')).values() 

How do I filter the Review model with the related_products field in the Blog model? Or is it possible to just include the product view in my Post template? Thanks in advance for your help!

my models:

class Post(models.Model):
    user = models.ForeignKey(User)
    title = models.CharField(max_length=100)
    related_product = models.ManyToManyField(ProductProfile, blank=True)

    def __str__(self):
        return self.title

class ProductProfile(models.Model):
    product = models.CharField(max_length=80)
    avatar = models.ImageField(upload_to='profile_images', blank=True)
    price = models.IntegerField()
    info = models.TextField(blank=True)
    category = models.ForeignKey(ProductCategories)
    link = models.URLField(blank=True)
    bookmarks = models.ManyToManyField(User, blank=True,related_name='product_bookmarks')

    def __str__(self):
         return self.product

class Review(models.Model):
    user = models.ForeignKey(User)
    product = models.ForeignKey(ProductProfile)
    rating = models.IntegerField()
    review = models.TextField(blank=True)

    def __str__(self):
        return self.user.username

My views:

def post(request, post_id):
    try:
        post = Post.objects.get(pk=post_id)
    except Post.DoesNotExist:
        raise Http404

    product_rating = Review.objects.filter(product_id=productprofile_id).aggregate(Avg('rating')).values()

    return render(request, 'app/blog.html', {'post': post, 'product_rating': product_rating})

def product(request, productprofile_id):
    try:
        product = ProductProfile.objects.get(pk=productprofile_id)
    except ProductProfile.DoesNotExist:
        raise Http404
    product_media = ProductMedia.objects.filter(product_id=productprofile_id)
    product_brand = BrandProfile.objects.filter(products__id=productprofile_id)
    review = Review.objects.filter(product_id=productprofile_id)
    product_rating = Review.objects.filter(product_id=productprofile_id).aggregate(Avg('rating')).values()

    return render(request, 'app/product.html', {'product': product, 'product_media': product_media, 'review': review, 'product_rating': product_rating, 'product_brand': product_brand,})

My template tag:

{% for value in product_rating %} {{ value }} {%endfor%}

回答1:


I think you should make the rating a method on the ProductProfile model, which returns the average of the reviews for that product:

class ProductProfile(models.Model):
    ...
    def avg_rating(self):
        return self.review_set.aggregate(Avg('rating')).values()

Now you can remove it from both views, and call {{ product.avg_rating }} when you iterate through the products in the post view.




回答2:


Maybe

{% for productprofile in post.related_product_set.all %} 

{{ productprofile.review.rating }} 

{% endfor %}

? I can't remember if the .all is required.



来源:https://stackoverflow.com/questions/31702487/django-filter-a-model-with-a-field-from-another-model

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!