0

私が欲しいのは、今週/今月/今年などの最新の製品を入手できるようにすることです。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))たとえば、最新の週の後で、製品をどのように並べ替えますか?

この構造も決まっていないので、他の方法でモデルを構築する場合は教えてください!

4

2 に答える 2

1

最初のアイデア:

ProductStatisticビューでは、クエリセットをループしてすべてのオブジェクトに変数rankingを追加し、そのオブジェクトをリストに追加するよりも、今日の をクエリできます。次に、並べ替えrankingて、リストをテンプレートに渡します。

2番目のアイデア:

フィールド (管理者には非表示) を作成し、 pre_save-signalrankingを使用して、オブジェクトがデータベースに保存されるたびに ur 式の解を書き込みます。今、あなたはすることができます ProductStatistic.objects.filter(date=today()).order_by('ranking')

どちらのアイデアにも長所と短所がありますが、私は 2 番目のアイデアの方が好きです

コメントへの応答として編集

  • アイデア 2 を使用する

  • 次のようにフィルタリングするビューを作成します。ProductStatistic.objects.filter(product= aProductObject, date__gte=startdate, date__lte=enddate)

    クエリセットをループして、次のようにしますaProductObject.ranking+= qs_obj.ranking

  • クエリセットのソートされたリストをテンプレートに渡します

基本的に両方のアイデアの組み合わせ

あなた自身の答えに編集してください

あなたのソリューションは、私が提案したものから遠く離れていませんが、SQL 空間にあります。

しかし、別の解決策:

ヒットモデルを作る:

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()

購入ビューで、ヒットオブジェクトを取得して設定しますpurchased=True

これで、テンプレート/DB-Tools で実際の統計を行うことができます。

もちろん、時間の経過とともに多くの DB オブジェクトが生成される可能性があるため、適切な削除戦略を検討する必要があります (3 か月後のデータを別のモデルに合計するなどMonthlyHitArchive) 。

この統計を表示すると大量の DB トラフィックが発生すると思われる場合は、キャッシングの使用を検討する必要があります。

于 2009-12-13T03:16:00.437 に答える
0

私はこれを解決したくない方法で解決しました。とを追加week_rankしてから、モデルに以下を追加しました。month_rankoverall_rankProductProductStatistic

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()

より良い解決策があれば、未解決のままにします。

于 2009-12-15T13:02:56.200 に答える