Prepare for the removal of Check.user_id

This commit is contained in:
Pēteris Caune 2019-01-18 14:59:01 +02:00
parent 654516412e
commit e1b999e83a
No known key found for this signature in database
GPG Key ID: E28D7679E9A9EDE2
5 changed files with 45 additions and 37 deletions

View File

@ -52,7 +52,7 @@ class ProfileAdmin(admin.ModelAdmin):
def get_queryset(self, request): def get_queryset(self, request):
qs = super(ProfileAdmin, self).get_queryset(request) qs = super(ProfileAdmin, self).get_queryset(request)
qs = qs.annotate(Count("member", distinct=True)) qs = qs.annotate(Count("member", distinct=True))
qs = qs.annotate(Count("user__check", distinct=True)) qs = qs.annotate(num_checks=Count("user__project__check", distinct=True))
return qs return qs
@mark_safe @mark_safe
@ -66,14 +66,13 @@ class ProfileAdmin(admin.ModelAdmin):
@mark_safe @mark_safe
def checks(self, obj): def checks(self, obj):
num_checks = obj.user__check__count pct = 100 * obj.num_checks / max(obj.check_limit, 1)
pct = 100 * num_checks / max(obj.check_limit, 1)
pct = min(100, int(pct)) pct = min(100, int(pct))
return """ return """
<span class="bar"><span style="width: %dpx"></span></span> <span class="bar"><span style="width: %dpx"></span></span>
&nbsp; %d of %d &nbsp; %d of %d
""" % (pct, num_checks, obj.check_limit) """ % (pct, obj.num_checks, obj.check_limit)
def invited(self, obj): def invited(self, obj):
return "%d of %d" % (obj.member__count, obj.team_limit) return "%d of %d" % (obj.member__count, obj.team_limit)
@ -106,8 +105,8 @@ class HcUserAdmin(UserAdmin):
def get_queryset(self, request): def get_queryset(self, request):
qs = super().get_queryset(request) qs = super().get_queryset(request)
qs = qs.annotate(Count("check", distinct=True)) qs = qs.annotate(num_checks=Count("project__check", distinct=True))
qs = qs.annotate(Count("channel", distinct=True)) qs = qs.annotate(num_channels=Count("project__channel", distinct=True))
return qs return qs
@ -115,19 +114,19 @@ class HcUserAdmin(UserAdmin):
def engagement(self, user): def engagement(self, user):
result = "" result = ""
if user.check__count == 0: if user.num_checks == 0:
result += "0 checks, " result += "0 checks, "
elif user.check__count == 1: elif user.num_checks == 1:
result += "1 check, " result += "1 check, "
else: else:
result += "<strong>%d checks</strong>, " % user.check__count result += "<strong>%d checks</strong>, " % user.num_checks
if user.channel__count == 0: if user.num_channels == 0:
result += "0 channels" result += "0 channels"
elif user.channel__count == 1: elif user.num_channels == 1:
result += "1 channel, " result += "1 channel, "
else: else:
result += "<strong>%d channels</strong>, " % user.channel__count result += "<strong>%d channels</strong>, " % user.num_channels
return result return result

View File

@ -9,7 +9,7 @@ class BadgesTestCase(BaseTestCase):
Check.objects.create(user=self.alice, tags="foo a-B_1 baz@", Check.objects.create(user=self.alice, tags="foo a-B_1 baz@",
project=self.project) project=self.project)
Check.objects.create(user=self.bob, tags="bobs-tag", Check.objects.create(user=self.bob, tags="bobs-tag",
project=self.project) project=self.bobs_project)
r = self.client.get("/accounts/profile/badges/") r = self.client.get("/accounts/profile/badges/")
self.assertContains(r, "foo.svg") self.assertContains(r, "foo.svg")

View File

@ -311,21 +311,21 @@ def notifications(request):
def badges(request): def badges(request):
_ensure_own_team(request) _ensure_own_team(request)
teams = [request.profile] projects = [request.project]
for membership in request.user.memberships.all(): for membership in request.user.memberships.all():
teams.append(membership.team) projects.append(membership.project)
badge_sets = [] badge_sets = []
for team in teams: for project in projects:
tags = set() tags = set()
for check in Check.objects.filter(user=team.user): for check in Check.objects.filter(project=project):
tags.update(check.tags_list()) tags.update(check.tags_list())
sorted_tags = sorted(tags, key=lambda s: s.lower()) sorted_tags = sorted(tags, key=lambda s: s.lower())
sorted_tags.append("*") # For the "overall status" badge sorted_tags.append("*") # For the "overall status" badge
urls = [] urls = []
username = team.user.username username = project.owner.username
for tag in sorted_tags: for tag in sorted_tags:
if not re.match("^[\w-]+$", tag) and tag != "*": if not re.match("^[\w-]+$", tag) and tag != "*":
continue continue
@ -335,7 +335,7 @@ def badges(request):
"json": get_badge_url(username, tag, format="json"), "json": get_badge_url(username, tag, format="json"),
}) })
badge_sets.append({"team": team, "urls": urls}) badge_sets.append({"project": project, "urls": urls})
ctx = { ctx = {
"page": "profile", "page": "profile",

View File

@ -1,7 +1,7 @@
from django.contrib import admin from django.contrib import admin
from django.core.paginator import Paginator from django.core.paginator import Paginator
from django.db import connection from django.db import connection
from django.db.models import Count from django.db.models import Count, F
from django.utils.safestring import mark_safe from django.utils.safestring import mark_safe
from hc.api.models import Channel, Check, Flip, Notification, Ping from hc.api.models import Channel, Check, Flip, Notification, Ping
from hc.lib.date import format_duration from hc.lib.date import format_duration
@ -15,17 +15,22 @@ class ChecksAdmin(admin.ModelAdmin):
'all': ('css/admin/checks.css',) 'all': ('css/admin/checks.css',)
} }
search_fields = ["name", "user__email", "code"] search_fields = ["name", "code", "project__owner__email"]
list_display = ("id", "name_tags", "created", "code", "timeout_schedule", raw_id_fields = ("project", )
"status", "email", "last_start", "last_ping", "n_pings") list_display = ("id", "name_tags", "email", "created", "n_pings",
list_select_related = ("user", ) "timeout_schedule", "status", "last_start", "last_ping")
list_filter = ("status", "kind", "last_ping", list_filter = ("status", "kind", "last_ping",
"last_start") "last_start")
actions = ["send_alert"] actions = ["send_alert"]
def get_queryset(self, request):
qs = super().get_queryset(request)
qs = qs.annotate(email=F("project__owner__email"))
return qs
def email(self, obj): def email(self, obj):
return obj.user.email if obj.user else None return obj.email
def name_tags(self, obj): def name_tags(self, obj):
if not obj.tags: if not obj.tags:
@ -137,9 +142,9 @@ class LargeTablePaginator(Paginator):
@admin.register(Ping) @admin.register(Ping)
class PingsAdmin(admin.ModelAdmin): class PingsAdmin(admin.ModelAdmin):
search_fields = ("owner__name", "owner__code", "owner__user__email") search_fields = ("owner__name", "owner__code")
readonly_fields = ("owner", ) readonly_fields = ("owner", )
list_select_related = ("owner", "owner__user") list_select_related = ("owner", )
list_display = ("id", "created", "owner", "email", "scheme", "method", list_display = ("id", "created", "owner", "email", "scheme", "method",
"ua") "ua")
list_filter = ("created", SchemeListFilter, MethodListFilter, list_filter = ("created", SchemeListFilter, MethodListFilter,
@ -147,8 +152,13 @@ class PingsAdmin(admin.ModelAdmin):
paginator = LargeTablePaginator paginator = LargeTablePaginator
def get_queryset(self, request):
qs = super().get_queryset(request)
qs = qs.annotate(email=F("owner__project__owner__email"))
return qs
def email(self, obj): def email(self, obj):
return obj.owner.user.email if obj.owner.user else None return obj.email
@admin.register(Channel) @admin.register(Channel)
@ -158,21 +168,20 @@ class ChannelsAdmin(admin.ModelAdmin):
'all': ('css/admin/channels.css',) 'all': ('css/admin/channels.css',)
} }
search_fields = ["value", "user__email"] search_fields = ["value", "project__owner__email"]
list_select_related = ("user", )
list_display = ("id", "name", "email", "formatted_kind", "value", list_display = ("id", "name", "email", "formatted_kind", "value",
"num_notifications") "num_notifications")
list_filter = ("kind", ) list_filter = ("kind", )
raw_id_fields = ("user", "checks", ) raw_id_fields = ("project", "checks", )
def get_queryset(self, request): def get_queryset(self, request):
qs = super().get_queryset(request) qs = super().get_queryset(request)
qs = qs.annotate(Count("notification", distinct=True)) qs = qs.annotate(Count("notification", distinct=True))
qs = qs.annotate(email=F("project__owner__email"))
return qs return qs
def email(self, obj): def email(self, obj):
return obj.user.email if obj.user else None return obj.email
@mark_safe @mark_safe
def formatted_kind(self, obj): def formatted_kind(self, obj):

View File

@ -29,8 +29,8 @@
<p id="badges-description"> <p id="badges-description">
{% site_name %} provides status badges for each of the tags {% site_name %} provides status badges for each of the tags
you have used. Additionally, the "{% site_name %}" you have used. Additionally, the "{% site_name %}"
badge shows the overall status of all checks in your badge shows the overall status of all checks in a
account. The badges have public, but hard-to-guess project. The badges have public, but hard-to-guess
URLs. You can use them in your READMEs, URLs. You can use them in your READMEs,
dashboards or status pages. dashboards or status pages.
</p> </p>
@ -47,7 +47,7 @@
<table id="badges-svg" class="badges table"> <table id="badges-svg" class="badges table">
{% for badge_set in badges %} {% for badge_set in badges %}
<tr> <tr>
<th colspan="2">{{ badge_set.team }}</th> <th colspan="2">{{ badge_set.project }}</th>
</tr> </tr>
{% for urldict in badge_set.urls %} {% for urldict in badge_set.urls %}
<tr> <tr>
@ -64,7 +64,7 @@
<table id="badges-json" class="badges table"> <table id="badges-json" class="badges table">
{% for badge_set in badges %} {% for badge_set in badges %}
<tr> <tr>
<th colspan="2">{{ badge_set.team }}</th> <th colspan="2">{{ badge_set.project }}</th>
</tr> </tr>
{% for urldict in badge_set.urls %} {% for urldict in badge_set.urls %}