Django 按日期间隔和重量对产品进行分类
我想要的是能够获得本周/本月/本年等最热门的产品。因此,我有一个名为Django 按日期间隔和重量对产品进行分类,django,django-models,django-orm,Django,Django Models,Django Orm,我想要的是能够获得本周/本月/本年等最热门的产品。因此,我有一个名为ProductStatistics的模型,它将每天记录每次点击和每次购买。这是我必须使用的模型: class Product(models.Model): name = models.CharField(_("Name"), max_length=200) slug = models.SlugField() description = models.Te
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)
在最近一周的(点击+(购买*2))
之后,您将如何对产品进行排序
这种结构也不是一成不变的,所以如果你想用任何其他方式构造模型,请告诉我 第一个想法:
在视图中,您可以查询今天的ProductStatistic
,然后循环查询集,向每个对象添加一个变量ranking
,并将该对象添加到列表中。然后在排名之后排序
,并将列表传递给您的模板
第二个想法:
创建一个文件排名
(对管理员隐藏),并在每次使用。现在您可以执行ProductStatistic.objects.filter(date=today()).order\u by('ranking')
两种想法都有利弊,但我更喜欢第二种想法
编辑作为对注释的响应
- 使用想法2
- 编写一个视图,在其中进行如下筛选:
循环查询集并执行类似于ProductStatistic.objects.filter(product=aProductObject,date\uu gte=startdate,date\uu lte=enddate)
aProductObject.ranking+=qs_obj.ranking
- 将查询集的排序列表传递给模板
class Hit(models.Model):
date = models.DateTimeFiles(auto_now=True)
product = models.ForeignKey(Product)
purchased= models.BooleanField(default=False)
session = models.CharField(max_length=40)
在显示产品的视图中,检查会话中是否有命中对象,以及对象。如果没有,你就保存它
Hit(product=product,
date=datetime.datetime.now(),
session=request.session.session_key).save()
在purchase视图中,您获得命中对象并设置purchased=True
现在,在模板/DB工具中,您可以进行真正的统计
当然,它会在一段时间内生成大量的DB对象,因此您应该考虑一个好的删除策略(比如将3个月后的数据汇总到另一个模型MonthlyHitArchive
)
如果你认为显示这个统计数据会产生大量的DB流量,你应该考虑使用一些缓存。
< P>我用我不想解决的方式解决了这个问题。我将周排名
、月排名
和总体排名
添加到产品
中,然后我将以下内容添加到我的产品统计
模型中
def calculate_rank(self, days_ago=7, overall=False):
if overall:
return self._default_manager.all().extra(
select = {'rank': 'SUM(hits + (clicks * 2))'}
).values()[0]['rank']
else:
return self._default_manager.filter(
date__gte = datetime.today()-timedelta(days_ago),
date__lte = datetime.today()
).extra(
select = {'rank': 'SUM(hits + (clicks * 2))'}
).values()[0]['rank']
def save(self, *args, **kwargs):
super(ProductStatistic, self).save(*args, **kwargs)
t = Product.objects.get(pk=self.product.id)
t.week_rank = self.calculate_rank()
t.month_rank = self.calculate_rank(30)
t.overall_rank = self.calculate_rank(overall=True)
t.save()
如果有更好的解决方案,我就不去解决它。问题是ProductStatistics每周会返回7个对象,我想要这些对象的总和,基本上按它来订购产品。我猜我必须使用原始SQL或.extra()来实现这一点。但是我不知道怎么做,因为我不太擅长SQL。