doorcontrol: Convert HIDEvent.is_red to newly added GeneratedField

model.GeneratedField is new in Django 5.0
This commit is contained in:
Adam Goldsmith 2023-12-04 12:01:12 -05:00
parent 71ab17b2ce
commit cacde865c0
3 changed files with 68 additions and 47 deletions

View File

@ -11,41 +11,24 @@ class DoorAdmin(admin.ModelAdmin):
pass pass
class IsRedFilter(admin.SimpleListFilter):
title = "Is Red"
parameter_name = "is_red"
def lookups(self, request, model_admin):
return (
("1", "Yes"),
("0", "No"),
)
def queryset(self, request, queryset):
if self.value() is None:
return queryset
else:
return queryset.filter(is_red=(self.value() == "1"))
@admin.register(HIDEvent) @admin.register(HIDEvent)
class HIDEventAdmin(DjangoObjectActions, admin.ModelAdmin): class HIDEventAdmin(DjangoObjectActions, admin.ModelAdmin):
search_fields = ["forename", "surname", "cardholder_id"] search_fields = ["forename", "surname", "cardholder_id"]
list_display = ["timestamp", "door", "event_type", "description", "is_red"] list_display = ["timestamp", "door", "event_type", "description", "_is_red"]
list_filter = [ list_filter = [
"timestamp", "timestamp",
"door", "door",
"event_type", "event_type",
IsRedFilter, "is_red",
] ]
readonly_fields = ["decoded_card_number"] readonly_fields = ["decoded_card_number"]
changelist_actions = ("refresh_all_doors",) changelist_actions = ("refresh_all_doors",)
def get_queryset(self, request): def get_queryset(self, request):
return super().get_queryset(request).with_is_red().with_decoded_card_number() return super().get_queryset(request).with_decoded_card_number()
@admin.display(boolean=True) @admin.display(boolean=True)
def is_red(self, obj): def _is_red(self, obj):
return obj.is_red return obj.is_red
def has_add_permission(self, request, obj=None): def has_add_permission(self, request, obj=None):

View File

@ -0,0 +1,40 @@
# Generated by Django 5.0 on 2023-12-04 16:53
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("doorcontrol", "0003_door_ip"),
]
operations = [
migrations.AddField(
model_name="hidevent",
name="is_red",
field=models.GeneratedField(
db_persist=False,
expression=models.Q(
(
"event_type__in",
[
1022,
1023,
2024,
2029,
2036,
2042,
2043,
2046,
4041,
4042,
4043,
4044,
4045,
],
)
),
output_field=models.BooleanField(),
),
),
]

View File

@ -2,7 +2,7 @@ from datetime import datetime
from django.conf import settings from django.conf import settings
from django.db import models from django.db import models
from django.db.models import ExpressionWrapper, F, Func, Q from django.db.models import F, Func, Q
from django.db.models.functions import Mod from django.db.models.functions import Mod
from django.utils import timezone from django.utils import timezone
@ -26,31 +26,6 @@ class Door(models.Model):
class HIDEventQuerySet(models.QuerySet): class HIDEventQuerySet(models.QuerySet):
def with_is_red(self):
"""Based on `function isRedEvent` from /html/hid-global.js on a HID EDGE EVO Solo"""
return self.annotate(
is_red=ExpressionWrapper(
Q(
event_type__in=[
HIDEvent.EventType.DENIED_ACCESS_CARD_NOT_FOUND,
HIDEvent.EventType.DENIED_ACCESS_ACCESS_PIN_NOT_FOUND,
HIDEvent.EventType.DENIED_ACCESS_SCHEDULE,
HIDEvent.EventType.DENIED_ACCESS_WRONG_PIN,
HIDEvent.EventType.DENIED_ACCESS_CARD_EXPIRED,
HIDEvent.EventType.DENIED_ACCESS_PIN_LOCKOUT,
HIDEvent.EventType.DENIED_ACCESS_UNASSIGNED_CARD,
HIDEvent.EventType.DENIED_ACCESS_PIN_EXPIRED,
HIDEvent.EventType.DOOR_FORCED_ALARM,
HIDEvent.EventType.DOOR_HELD_ALARM,
HIDEvent.EventType.TAMPER_SWITCH_ALARM,
HIDEvent.EventType.AC_FAILURE,
HIDEvent.EventType.BATTERY_FAILURE,
]
),
output_field=models.BooleanField(),
)
)
def with_decoded_card_number(self): def with_decoded_card_number(self):
# TODO: CONV and BIT_COUNT are MySQL/MariaDB specific # TODO: CONV and BIT_COUNT are MySQL/MariaDB specific
class Conv(Func): class Conv(Func):
@ -137,6 +112,29 @@ class HIDEvent(models.Model):
max_length=8, blank=True, null=True, db_column="rawCardNumber" max_length=8, blank=True, null=True, db_column="rawCardNumber"
) )
# Based on `function isRedEvent` from /html/hid-global.js on a HID EDGE EVO Solo
is_red = models.GeneratedField(
expression=Q(
event_type__in=[
EventType.DENIED_ACCESS_CARD_NOT_FOUND,
EventType.DENIED_ACCESS_ACCESS_PIN_NOT_FOUND,
EventType.DENIED_ACCESS_SCHEDULE,
EventType.DENIED_ACCESS_WRONG_PIN,
EventType.DENIED_ACCESS_CARD_EXPIRED,
EventType.DENIED_ACCESS_PIN_LOCKOUT,
EventType.DENIED_ACCESS_UNASSIGNED_CARD,
EventType.DENIED_ACCESS_PIN_EXPIRED,
EventType.DOOR_FORCED_ALARM,
EventType.DOOR_HELD_ALARM,
EventType.TAMPER_SWITCH_ALARM,
EventType.AC_FAILURE,
EventType.BATTERY_FAILURE,
]
),
output_field=models.BooleanField(),
db_persist=False,
)
@classmethod @classmethod
def from_xml_attributes(cls, door: Door, attrib: dict[str:str]): def from_xml_attributes(cls, door: Door, attrib: dict[str:str]):
field_lookup = { field_lookup = {