Появилась задача для подсчета числа переходов на Django сайте.
Для этого создадим промежуточную страницу /go/<thing_id>/:
Обработчик страницы будет производить две простых вещи:
- увеличение счетчика числа переходов;
- перенаправление пользователя на нужный урл;
1. Для начала напишем простенький тест:
2. Добавим таблицу в БД для подсчета кликов:
Для этого создадим промежуточную страницу /go/<thing_id>/:
Обработчик страницы будет производить две простых вещи:
- увеличение счетчика числа переходов;
- перенаправление пользователя на нужный урл;
1. Для начала напишем простенький тест:
class ThingCounterTest(unittest.TestCase):
def setUp(self):
self.thing _ = Thing.objects.get_or_create(name="test_channel")
def tearDown(self):
self.thing.delete()
def test_thing_counters(self):
self.thing.add_click()
self.assertEqual(self.thing.clicks_today, 1)
self.assertEqual(self.thing.clicks_yesterday, 0)
self.assertEqual(self.thing.clicks_last_week, 1)
self.assertEqual(self.thing.clicks_last_month, 1)
2. Добавим таблицу в БД для подсчета кликов:
class ThingClick(models.Model):
thing = models.ForeignKey(
Thing, related_name='clicks',
on_delete=models.CASCADE)
clicked_at = models.DateTimeField(auto_now_add=True)
class Meta:
verbose_name = u"Клик на товар"
verbose_name_plural = u"Клики на товары"
Не забываем сделать миграцию.
3. Добавим функции для подсчета кликов за последние периоды:
(models.py)
class Thing(models.Model):
...
def add_click(self):
self.clicks.create()
@property
def clicks_today(self):
yesterday = timezone.now().date() - timedelta(days=1)
return self.clicks.filter(
clicked_at__gt=yesterday).count()
@property
def clicks_yesterday(self):
yesterday = timezone.now().date() - timedelta(days=1)
return self.clicks.filter(
clicked_at__gte=yesterday,
clicked_at__lt=timezone.now().date()).count()
@property
def clicks_last_week(self):
week_ago = timezone.now().date() - timedelta(days=7)
return self.clicks.filter(clicked_at__gte=week_ago).count()
@property
def clicks_last_month(self):
month_ago = timezone.now().date() - timedelta(days=30)
return self.clicks.filter(clicked_at__gte=month_ago).count()
4. напишем вид, который будет считать ссылки и редиректить на нужную страницу (ссылка на которую у меня уже хранится в thing.link):
(views.py)
def thing_click_admitad(request, thing_id=None):
"""
Переход по ссылке thing.link со счетчиком кликов
по каналу
"""
if thing_id:
thing = get_object_or_404(
Thing.objects.select_related("thing_set__channel"),
id=thing_id)
try:
thing.add_click()
except Exception, e:
logger.error("Failed to add a click for thing: " + str(e))
if thing.link:
return HttpResponseRedirect(thing.link)
else:
raise Http404
5. Добавим в urls.py соответствующий шаблон ссылок:
url(r"^go/(?P<thing_id>[0-9]+)/$",
"statistic.views.thing_click",
name="counted_link"),
6. Наконец, добавим в админку отображение результатов нашей статистики:
class ThingAdmin(admin.ModelAdmin):
list_display = (
"name", "url", "clicks_today", "clicks_yesterday",
"clicks_last_week", "clicks_last_month")
def clicks_today(self, obj):
return obj.clicks_today
clicks_today.short_description = u'Кликов сегодня'
def clicks_yesterday(self, obj):
return obj.clicks_yesterday
clicks_yesterday.short_description = u'Кликов вчера'
def clicks_last_week(self, obj):
return obj.clicks_last_week
clicks_last_week.short_description = u'Кликов за последнюю неделю'
def clicks_last_month(self, obj):
return obj.clicks_last_month
clicks_last_month.short_description = u'Кликов за последний месяц'
Комментариев нет:
Отправить комментарий