按日期间隔和重量对产品进行排序
我想要的是能够获得本周/本月/今年等最热门的产品。因此,我有一个名为 ProductStatistics
的模型,它将每天记录每次点击和每次购买。这是我必须使用的模型:
class Product(models.Model):
name = models.CharField(_("Name"), max_length=200)
slug = models.SlugField()
description = models.TextField(_("Description"))
picture = models.ImageField(upload_to=product_upload_path, blank=True)
category = models.ForeignKey(ProductCategory)
prices = models.ManyToManyField(Store, through='Pricing')
objects = ProductManager()
class Meta:
ordering = ('name', )
def __unicode__(self):
return self.name
class ProductStatistic(models.Model):
# There is only 1 `date` each day. `date` is
# set by datetime.today().date()
date = models.DateTimeField(default=datetime.now)
hits = models.PositiveIntegerField(default=0)
purchases = models.PositiveIntegerField(default=0)
product = models.ForeignKey(Product)
class Meta:
ordering = ('product', 'date', 'purchases', 'hits', )
def __unicode__(self):
return u'%s: %s - %s hits, %s purchases' % (self.product.name, str(self.date).split(' ')[0], self.hits, self.purchases)
在最近一周的(hits+(purchases*2))
之后,您将如何对产品进行排序?
这种结构也不是一成不变的,所以如果您想以任何其他方式构建模型,请告诉我们!
What I want is to be able to get this weeks/this months/this years etc. hotest products. So I have a model named ProductStatistics
that will log each hit and each purchase on a day-to-day basis. This is the models I have got to work with:
class Product(models.Model):
name = models.CharField(_("Name"), max_length=200)
slug = models.SlugField()
description = models.TextField(_("Description"))
picture = models.ImageField(upload_to=product_upload_path, blank=True)
category = models.ForeignKey(ProductCategory)
prices = models.ManyToManyField(Store, through='Pricing')
objects = ProductManager()
class Meta:
ordering = ('name', )
def __unicode__(self):
return self.name
class ProductStatistic(models.Model):
# There is only 1 `date` each day. `date` is
# set by datetime.today().date()
date = models.DateTimeField(default=datetime.now)
hits = models.PositiveIntegerField(default=0)
purchases = models.PositiveIntegerField(default=0)
product = models.ForeignKey(Product)
class Meta:
ordering = ('product', 'date', 'purchases', 'hits', )
def __unicode__(self):
return u'%s: %s - %s hits, %s purchases' % (self.product.name, str(self.date).split(' ')[0], self.hits, self.purchases)
How would you go about sorting the Products after say (hits+(purchases*2))
the latest week?
This structure isn't set in stone either, so if you would structure the models in any other way, please tell!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
第一个想法:
在视图中,您可以查询今天的
ProductStatistic
,然后循环查询集并向每个对象添加一个变量ranking
并将该对象添加到列表中。然后按照ranking
进行排序,并将列表传递给您的模板。第二个想法:
创建一个归档的排名(对管理员隐藏),并在每次将对象保存到数据库时使用 pre_save-signal。现在您可以执行
ProductStatistic.objects.filter(date=today()).order_by('ranking')
两种想法都有优点和缺点,但我喜欢第二个想法更多
编辑作为对评论的响应
编写一个视图,在其中进行如下过滤:
ProductStatistic.objects.filter(product= aProductObject, date__gte=startdate, date__lte=enddate)
循环查询集并执行诸如
aProductObject.ranking+= qs_obj.ranking
之类的操作
将查询集的排序列表传递给模板
基本上是两种想法的组合
,编辑为您自己的回答
你的解决方案与我的建议相距不远 - 但在 sql-space 中。
但另一个解决方案:
创建一个命中模型:
在您的视图中显示您检查的产品,是否有会话和对象的命中对象。如果没有,您将其保存
在购买视图中,您将获得命中对象并设置
purchased=True
现在,您可以在模板/数据库工具中进行真正的统计。
当然,随着时间的推移,它会生成大量的 DB-Objects,因此您应该考虑一个好的删除策略(例如将 3 个月后的数据求和到另一个模型
MonthlyHitArchive
),如果您认为,显示此统计信息会产生大量数据库流量,您应该考虑使用一些缓存。
first idea:
in the view you could query for today's
ProductStatistic
, than loop over the the queryset and add a variableranking
to every object and add that object to a list. Then just sort afterranking
and pass the list to ur template.second idea:
create a filed
ranking
(hidden for admin) and write the solution of ur formula each time the object is saved to the database by using a pre_save-signal. Now you can doProductStatistic.objects.filter(date=today()).order_by('ranking')
Both ideas have pros&cons, but I like second idea more
edit as response to the comment
Use Idea 2
Write a view, where you filter like this:
ProductStatistic.objects.filter(product= aProductObject, date__gte=startdate, date__lte=enddate)
loop over the queryset and do somthing like
aProductObject.ranking+= qs_obj.ranking
pass a sorted list of the queryset to the template
Basically a combination of both ideas
edit to your own answer
Your solution isn't far away from what I suggested — but in sql-space.
But another solution:
Make a Hit-Model:
in your view for displaying a product you check, if there is a Hit-object with the session, and object. if not, you save it
in your purchase view you get the Hit-object and set
purchased=True
Now in your templates/DB-Tools you can do real statistics.
Of course it can generate a lot of DB-Objects over the time, so you should think about a good deletion-strategy (like sum the data after 3 month into another model
MonthlyHitArchive
)If you think, that displaying this statistics would generate to much DB-Traffic, you should consider using some caching.
我以我不想解决的方式解决了这个问题。我将
week_rank
、month_rank
和overall_rank
添加到Product
,然后将以下内容添加到我的ProductStatistic模型。
如果有更好的解决方案,我将不予解决。
I solved this the way I didn't want to solve it. I added
week_rank
,month_rank
andoverall_rank
toProduct
and then I just added the following to myProductStatistic
model.I'll leave it unsolved if there is a better solution.