Skip to content

Commit c5e1f7a

Browse files
committed
Resolves #66, uses already existing 'created' fields to apply a 30-day window to visits and versions to get top lists for homepage; disabled selecting of system and incrementing of num visits in counter to save two (2) DB queries as information is redundant to SystemVisit
1 parent 4882283 commit c5e1f7a

File tree

3 files changed

+56
-30
lines changed

3 files changed

+56
-30
lines changed

dbdb/core/models.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,7 @@ def current(self):
204204
if self.id is None:
205205
return SystemVersion(system=self)
206206

207-
return self.systemversion_set.get(is_current=True)
207+
return self.versions.get(is_current=True)
208208

209209
def get_absolute_url(self):
210210
return reverse('system', args=[self.slug])
@@ -271,7 +271,7 @@ def __str__(self):
271271
# SystemVisit
272272
# ==============================================
273273
class SystemVisit(models.Model):
274-
system = models.ForeignKey('System', models.CASCADE, related_name='counter')
274+
system = models.ForeignKey('System', models.CASCADE, related_name='visits')
275275
ip_address = models.GenericIPAddressField(null=False)
276276
user_agent = models.CharField(max_length=128, blank=True, null=False)
277277
created = models.DateTimeField(default=timezone.now)
@@ -308,7 +308,7 @@ class Meta:
308308
class SystemVersion(models.Model):
309309

310310
# Internal Version Meta-data
311-
system = models.ForeignKey('System', models.CASCADE)
311+
system = models.ForeignKey('System', models.CASCADE, related_name='versions')
312312
creator = models.ForeignKey(settings.AUTH_USER_MODEL, models.PROTECT)
313313
meta = models.ForeignKey('SystemVersionMetadata', models.SET_NULL, blank=True, null=True)
314314
ver = models.PositiveIntegerField('Version No.', default=1)

dbdb/core/views.py

Lines changed: 49 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
from haystack.query import SearchQuerySet
3838
from lxml import etree
3939
import jwt
40+
import pytz
4041
# project imports
4142
from dbdb.core.forms import CreateUserForm, SystemForm, SystemVersionForm, SystemVersionMetadataForm, SystemFeaturesForm, \
4243
SystemVersionEditForm
@@ -782,12 +783,12 @@ def post(self, request):
782783
return JsonResponse({ 'status':'bot' })
783784

784785
## Update the system's counter
785-
system = None
786-
with transaction.atomic():
787-
system = System.objects.select_for_update().get(pk=pk)
788-
system.view_count += 1
789-
system.save()
790-
#pass
786+
# system = None
787+
# with transaction.atomic():
788+
# system = System.objects.select_for_update().get(pk=pk)
789+
# system.view_count += 1
790+
# system.save()
791+
# pass
791792

792793
# And add a SystemVisit entry
793794
x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR')
@@ -796,14 +797,18 @@ def post(self, request):
796797
else:
797798
ip = request.META.get('REMOTE_ADDR')
798799

799-
system_visit = SystemVisit(system=system, ip_address=ip, user_agent=user_agent[:127])
800-
system_visit.save()
801-
800+
# save visit
801+
system_visit = SystemVisit.objects.create(
802+
system_id=pk,
803+
ip_address=ip,
804+
user_agent=user_agent[:127]
805+
)
806+
pass
802807
else:
803-
return JsonResponse({ 'status':('unrecognized counter: %r' % iss)}, status=400)
808+
return JsonResponse({ 'status':('unrecognized counter: %r' % iss) }, status=400)
804809
pass
805810
except jwt.ExpiredSignatureError:
806-
return JsonResponse({ 'status':'expired counter'}, status=400)
811+
return JsonResponse({ 'status':'expired counter' }, status=400)
807812

808813
return JsonResponse({ 'status':'ok' })
809814

@@ -1063,7 +1068,7 @@ def post(self, request, slug=None):
10631068
logo = system.current().logo
10641069
pass
10651070

1066-
system.systemversion_set.update(is_current=False)
1071+
system.versions.update(is_current=False)
10671072
db_version = system_version_form.save(commit=False)
10681073
db_version.creator = request.user
10691074
db_version.system = system
@@ -1198,7 +1203,7 @@ def post(self, request, slug):
11981203

11991204
system = System.objects.get(slug=slug)
12001205
version = SystemVersion.objects.get(id=request.POST['ver'])
1201-
system.systemversion_set.update(is_current=False)
1206+
system.versions.update(is_current=False)
12021207
version.is_current = True
12031208
system.ver = version.ver
12041209
system.modified = timezone.now()
@@ -1279,25 +1284,45 @@ def get(self, request):
12791284
# ==============================================
12801285
class HomeView(View):
12811286

1287+
ITEMS_TO_SHOW = 5
1288+
12821289
template_name = 'core/home.html'
12831290

12841291
def get(self, request):
1285-
items_to_show = 5
1286-
1292+
# calculate date window
1293+
start_date = timezone.now().astimezone(pytz.utc) - datetime.timedelta(days=30) # rolling 30 days
1294+
start_date = datetime.datetime.combine(start_date.date(), datetime.time(0, 0, 0))
1295+
start_date = pytz.utc.localize(start_date)
1296+
1297+
# get top systems by modified date
1298+
most_recent = System.objects \
1299+
.order_by('-modified')
1300+
most_recent = most_recent[:HomeView.ITEMS_TO_SHOW]
1301+
1302+
# get top systems by number of (windowed) versions
1303+
most_versions = System.objects \
1304+
.annotate(num_versions=Count('versions__id', filter=Q(versions__created__gte=start_date))) \
1305+
.order_by('-num_versions', 'name') \
1306+
.filter(num_versions__gt=0)
1307+
most_versions = most_versions[:HomeView.ITEMS_TO_SHOW]
1308+
1309+
# get top systems by number of (windowed) visits
1310+
most_visits = System.objects \
1311+
.annotate(num_visits=Count('visits__id', filter=Q(visits__created__gte=start_date))) \
1312+
.order_by('-num_visits', 'name') \
1313+
.filter(num_visits__gt=0)
1314+
most_visits = most_visits[:HomeView.ITEMS_TO_SHOW]
1315+
1316+
# count numb systems
12871317
num_systems = System.objects.all().count()
12881318

1289-
1290-
most_edited = System.objects.order_by('-ver', '-name')[:items_to_show]
1291-
most_recent = System.objects.order_by('-modified')[:items_to_show]
1292-
most_views = System.objects.order_by('-view_count')[:items_to_show]
1293-
1294-
return render(request, self.template_name, context={
1295-
'num_systems': num_systems,
1296-
'most_edited': most_edited,
1319+
return render(request, self.template_name, {
12971320
'most_recent': most_recent,
1298-
'most_views': most_views,
1321+
'most_versions': most_versions,
1322+
'most_visits': most_visits,
12991323

13001324
'no_nav_search': True,
1325+
'num_systems': num_systems,
13011326
})
13021327

13031328
pass

templates/core/home.html

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
{% extends 'base.html' %}
2+
{% load humanize %}
23
{% load staticfiles %}
34
{% load thumbnail %}
45

@@ -10,7 +11,7 @@
1011
<div class="row justify-content-md-center homepage-header">
1112
<div class="col col-md-12 col-sm-12 text-center">
1213
<h1 class="display-3">Database of Databases</h1>
13-
<p class="lead">Discover and learn about <b>{{ num_systems }}</b> database management systems</p>
14+
<p class="lead">Discover and learn about <b>{{ num_systems|intcomma }}</b> database management systems</p>
1415
<form id="mainsearch" action="{% url 'browse' %}" method="GET" >
1516
<div class="form-group">
1617
<input autofocus type="text" name="q" class="form-control form-control-lg" aria-describedby="Search field" placeholder="Search" style="max-width:700px;margin:0 auto;">
@@ -40,7 +41,7 @@ <h3>Most Recent</h3>
4041
<h3>Most Viewed</h3>
4142
<table class="table table-hover">
4243
<tbody>
43-
{% for item in most_views %}
44+
{% for item in most_visits %}
4445
{% include 'core/home-listitem.html' %}
4546
{% endfor %}
4647
</tbody>
@@ -50,7 +51,7 @@ <h3>Most Viewed</h3>
5051
<h3>Most Edited</h3>
5152
<table class="table table-hover">
5253
<tbody>
53-
{% for item in most_edited %}
54+
{% for item in most_versions %}
5455
{% include 'core/home-listitem.html' %}
5556
{% endfor %}
5657
</tbody>

0 commit comments

Comments
 (0)