kopia lustrzana https://github.com/wagtail/wagtail
Add Query/QueryDailyHits models into search promotions
rodzic
ef438ae3c0
commit
2566f0431d
|
@ -0,0 +1,16 @@
|
|||
from django.core.management.base import BaseCommand
|
||||
|
||||
from wagtail.contrib.search_promotions import models
|
||||
|
||||
|
||||
class Command(BaseCommand):
|
||||
def handle(self, **options):
|
||||
# Clean daily hits
|
||||
self.stdout.write("Cleaning daily hits records…")
|
||||
models.QueryDailyHits.garbage_collect()
|
||||
self.stdout.write("Done")
|
||||
|
||||
# Clean queries
|
||||
self.stdout.write("Cleaning query records…")
|
||||
models.Query.garbage_collect()
|
||||
self.stdout.write("Done")
|
|
@ -0,0 +1,58 @@
|
|||
# Generated by Django 3.1.8 on 2021-06-22 14:19
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("wagtailsearchpromotions", "0002_capitalizeverbose"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name="Query",
|
||||
fields=[
|
||||
(
|
||||
"id",
|
||||
models.AutoField(
|
||||
auto_created=True,
|
||||
primary_key=True,
|
||||
serialize=False,
|
||||
verbose_name="ID",
|
||||
),
|
||||
),
|
||||
("query_string", models.CharField(max_length=255, unique=True)),
|
||||
],
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name="QueryDailyHits",
|
||||
fields=[
|
||||
(
|
||||
"id",
|
||||
models.AutoField(
|
||||
auto_created=True,
|
||||
primary_key=True,
|
||||
serialize=False,
|
||||
verbose_name="ID",
|
||||
),
|
||||
),
|
||||
("date", models.DateField()),
|
||||
("hits", models.IntegerField(default=0)),
|
||||
(
|
||||
"query",
|
||||
models.ForeignKey(
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
related_name="daily_hits",
|
||||
to="wagtailsearchpromotions.query",
|
||||
),
|
||||
),
|
||||
],
|
||||
options={
|
||||
"verbose_name": "Query Daily Hits",
|
||||
"verbose_name_plural": "Query Daily Hits",
|
||||
"unique_together": {("query", "date")},
|
||||
},
|
||||
),
|
||||
]
|
|
@ -1,12 +1,102 @@
|
|||
import datetime
|
||||
|
||||
from django.conf import settings
|
||||
from django.db import models
|
||||
from django.utils import timezone
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
from wagtail.search.models import Query
|
||||
from wagtail.search.models import Query as WagtailSearchQuery
|
||||
from wagtail.search.utils import MAX_QUERY_STRING_LENGTH, normalise_query_string
|
||||
|
||||
|
||||
class Query(models.Model):
|
||||
query_string = models.CharField(max_length=MAX_QUERY_STRING_LENGTH, unique=True)
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
# Normalise query string
|
||||
self.query_string = normalise_query_string(self.query_string)
|
||||
|
||||
super().save(*args, **kwargs)
|
||||
|
||||
def add_hit(self, date=None):
|
||||
if date is None:
|
||||
date = timezone.now().date()
|
||||
daily_hits, created = QueryDailyHits.objects.get_or_create(
|
||||
query=self, date=date
|
||||
)
|
||||
daily_hits.hits = models.F("hits") + 1
|
||||
daily_hits.save()
|
||||
|
||||
def __str__(self):
|
||||
return self.query_string
|
||||
|
||||
@property
|
||||
def hits(self):
|
||||
hits = self.daily_hits.aggregate(models.Sum("hits"))["hits__sum"]
|
||||
return hits if hits else 0
|
||||
|
||||
@classmethod
|
||||
def garbage_collect(cls):
|
||||
"""
|
||||
Deletes all Query records that have no daily hits or editors picks
|
||||
"""
|
||||
extra_filter_kwargs = (
|
||||
{
|
||||
"editors_picks__isnull": True,
|
||||
}
|
||||
if hasattr(cls, "editors_picks")
|
||||
else {}
|
||||
)
|
||||
cls.objects.filter(daily_hits__isnull=True, **extra_filter_kwargs).delete()
|
||||
|
||||
@classmethod
|
||||
def get(cls, query_string):
|
||||
return cls.objects.get_or_create(
|
||||
query_string=normalise_query_string(query_string)
|
||||
)[0]
|
||||
|
||||
@classmethod
|
||||
def get_most_popular(cls, date_since=None):
|
||||
# TODO: Implement date_since
|
||||
return (
|
||||
cls.objects.filter(daily_hits__isnull=False)
|
||||
.annotate(_hits=models.Sum("daily_hits__hits"))
|
||||
.distinct()
|
||||
.order_by("-_hits")
|
||||
)
|
||||
|
||||
|
||||
class QueryDailyHits(models.Model):
|
||||
query = models.ForeignKey(
|
||||
Query, db_index=True, related_name="daily_hits", on_delete=models.CASCADE
|
||||
)
|
||||
date = models.DateField()
|
||||
hits = models.IntegerField(default=0)
|
||||
|
||||
@classmethod
|
||||
def garbage_collect(cls, days=None):
|
||||
"""
|
||||
Deletes all QueryDailyHits records that are older than a set number of days
|
||||
"""
|
||||
days = (
|
||||
getattr(settings, "WAGTAILSEARCH_HITS_MAX_AGE", 7) if days is None else days
|
||||
)
|
||||
min_date = timezone.now().date() - datetime.timedelta(days)
|
||||
|
||||
cls.objects.filter(date__lt=min_date).delete()
|
||||
|
||||
class Meta:
|
||||
unique_together = (("query", "date"),)
|
||||
verbose_name = _("Query Daily Hits")
|
||||
verbose_name_plural = _("Query Daily Hits")
|
||||
|
||||
|
||||
class SearchPromotion(models.Model):
|
||||
query = models.ForeignKey(
|
||||
Query, db_index=True, related_name="editors_picks", on_delete=models.CASCADE
|
||||
WagtailSearchQuery,
|
||||
db_index=True,
|
||||
related_name="editors_picks",
|
||||
on_delete=models.CASCADE,
|
||||
)
|
||||
page = models.ForeignKey(
|
||||
"wagtailcore.Page", verbose_name=_("page"), on_delete=models.CASCADE
|
||||
|
|
Ładowanie…
Reference in New Issue