帮助我改进鞋评网站的Django模型

1 投票
2 回答
1009 浏览
提问于 2025-04-15 19:59

我现在想要实现的目标:

  • 让我可以添加新的鞋子对象和鞋子评论对象。已经完成
  • 允许每双鞋子有“拥有者评论”。已经完成(我觉得是这样,但我的模型里可能还有可以改进的地方)
  • 允许对我定义的与特定鞋子相关的属性进行评分。最好能有个简单的方法来遍历与特定鞋子相关的所有评分字段。
  • 我的总体目标是能够轻松地建议与用户过去评分相似的鞋子。然后允许根据品牌、价格、高低排序以及鞋子使用的活动(标签)来过滤这些鞋子评论。

我觉得我快成功了,但在需要的关系上似乎还缺少了什么。如果能用以下方式获取高评分的鞋子评论,那就太方便了。

ShoeReview.objects.filter(owner_review__ratings__rating_attribute = 'overall').sort_by(owner_review__ratings__rating)

我觉得上面的代码是正确的吗?我对django还不是很熟悉,所以请原谅我可能的错误。和往常一样,我在发问之前已经在代码上琢磨了几天,所以别以为我只是随便发个帖子而没有付出努力。

以下是models.py文件的内容:

from django.db import models
from django.contrib.auth.models import User
from tagging.fields import TagField

class Brand(models.Model):
        def __unicode__(self):
                return self.name
        name = models.CharField(max_length=200)
        popularity = models.PositiveIntegerField(default=0)

class Shoe(models.Model):
        def __unicode__(self):
                return self.name
        brand = models.ForeignKey(Brand)
        name = models.CharField(max_length=200)
        description = models.TextField()
        price = models.PositiveIntegerField()
        buylink = models.URLField(verify_exists='true', default="http://www.amazon.com/gp/redirect.html?ie=UTF8&location=http%3A%2F%2Fwww.amazon.com%2FAthletic-Outdoor%2Fb%3Fie%3DUTF8%26node%3D679564011%26ref_%3Damb%5Flink%5F23091522%5F13&tag=runnshoerevi-20&linkCode=ur2&camp=1789&creative=390957", max_length=400)
        picture = models.ImageField(upload_to='shoes', blank=True, default="shoes/default_picture.jpg")
        youtube_video_id = models.CharField(max_length=25, blank=True)

class RatingAttributes(models.Model):
        def __unicode__(self):
                return self.attribute
        attribute = models.CharField(max_length=65)

class Rating(models.Model):
        def __unicode__(self):
                return "%s, %s: %s" % (str(self.author), str(self.rating_attribute), str(self.rating))

        rating_attribute = models.ForeignKey(RatingAttributes)
        author = models.ForeignKey(User)
        pub_date = models.DateTimeField(auto_now_add='true')
        rating = models.IntegerField(blank=True, null=True)

class OwnerReview(models.Model):
        def __unicode__(self):
                return self.comments
        author = models.ForeignKey(User)
        pub_date = models.DateTimeField(auto_now_add='true')
        shoe = models.ForeignKey(Shoe)
        youtube_video_id = models.CharField(max_length=25, blank=True)
        comments = models.TextField()
        # this field will be increased every time a user clicks "this review was helpful and all reviws will be sorted by the helpfulness value
        ratings = models.ForeignKey(Rating)
        helpfulness = models.IntegerField(default=0, blank=True)

class ShoeReview(models.Model):
        def __unicode__(self):
                return self.title
        pub_date = models.DateTimeField(auto_now_add='true')
        author = models.ForeignKey(User, related_name='reviews')
        title = models.CharField(max_length=200)
        keywords = models.CharField(max_length=800, blank=True, default="Shoe Review")
        slug = models.SlugField(unique=True)
        cur_shoe = models.ForeignKey(Shoe)
        staff_opinion = models.TextField()
        owner_review = models.ForeignKey(OwnerReview)
        shoe_activities = TagField()

2 个回答

1

不要这样做:

ShoeReview.objects.filter(owner_review__ratings__rating_attribute = 'overall').sort_by(owner_review__ratings__rating)

你应该调用:

ShoeReview.objects.filter(owner_review__ratings__rating_attribute__attribute = 'overall').order_by(owner_review__ratings__rating)

owner_review__ratings__rating_attribut 这个函数需要一个模型(它会从模型中获取主键,并在查询中使用)。另外,使用的是 order_by 方法,而不是 sort_by。除此之外,查询看起来没问题。试着运行一下,看看能不能得到结果,或者有没有错误。可以在 ./manage.py shell 中运行,这样可以快速方便地检查是否有效。

1

你应该这样做:

ShoeReview.objects\
          .filter(owner_review__ratings__rating_attribute__attribute='overall')\
          .order_by(owner_review__ratings__rating)

但实际上,使用一个管理工具会更好:

class BestShoesReviewManager(models.Manager):
    def get_query_set(self):
        qs =  super(DahlBookManager, self).get_query_set()
        return qs.filter(owner_review__ratings__rating_attribute__attribute= 'overall')\
                 .order_by(owner_review__ratings__rating)

这样你就可以这样做:

class ShoeReview(models.Model)

    objects = models.Manager() # The default manager.
    best = BestShoesReviewManager() # The best review manager.

所以在你的代码中,你可以这样写:

ShoeReview.objects.best()

撰写回答