Apply ruff lint rule DJ012 for model internals ordering

This commit is contained in:
Adam Goldsmith 2024-06-05 13:18:25 -04:00
parent c3f3294f2a
commit d8e6a69719
6 changed files with 100 additions and 100 deletions

View File

@ -22,6 +22,9 @@ class Door(models.Model):
help_text="Membershipworks field that grants members access to this door", help_text="Membershipworks field that grants members access to this door",
) )
def __str__(self):
return self.name
@property @property
def controller(self) -> DoorController: def controller(self) -> DoorController:
return DoorController( return DoorController(
@ -30,9 +33,6 @@ class Door(models.Model):
settings.HID_DOOR_PASSWORD, settings.HID_DOOR_PASSWORD,
) )
def __str__(self):
return self.name
@cached_property @cached_property
def card_formats(self): def card_formats(self):
return self.controller.get_cardFormats() return self.controller.get_cardFormats()
@ -149,8 +149,6 @@ class HIDEventQuerySet(models.QuerySet):
class HIDEvent(models.Model): class HIDEvent(models.Model):
objects = HIDEventQuerySet.as_manager()
class EventType(models.IntegerChoices): class EventType(models.IntegerChoices):
DENIED_ACCESS_CARD_NOT_FOUND = 1022, "Denied Access: Card Not Found" DENIED_ACCESS_CARD_NOT_FOUND = 1022, "Denied Access: Card Not Found"
DENIED_ACCESS_ACCESS_PIN_NOT_FOUND = 1023, "Denied Access Access: PIN Not Found" DENIED_ACCESS_ACCESS_PIN_NOT_FOUND = 1023, "Denied Access Access: PIN Not Found"
@ -224,6 +222,20 @@ class HIDEvent(models.Model):
db_persist=False, db_persist=False,
) )
objects = HIDEventQuerySet.as_manager()
class Meta:
constraints = [
models.UniqueConstraint(
fields=["door", "timestamp", "event_type"], name="unique_hidevent"
)
]
db_table = "hidevent"
ordering = ("-timestamp",)
def __str__(self):
return f"{self.door.name} {self.timestamp} - {self.description}"
@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 = {
@ -289,9 +301,6 @@ class HIDEvent(models.Model):
return event_types.get(self.event_type, f"Unknown Event Type {self.event_type}") return event_types.get(self.event_type, f"Unknown Event Type {self.event_type}")
def __str__(self):
return f"{self.door.name} {self.timestamp} - {self.description}"
def decoded_card_number(self) -> str | None: def decoded_card_number(self) -> str | None:
"""Requires annotations from `with_decoded_card_number`""" """Requires annotations from `with_decoded_card_number`"""
if self.raw_card_number is None: if self.raw_card_number is None:
@ -303,12 +312,3 @@ class HIDEvent(models.Model):
return "Invalid" return "Invalid"
else: else:
return "Not 26 bit card" return "Not 26 bit card"
class Meta:
constraints = [
models.UniqueConstraint(
fields=["door", "timestamp", "event_type"], name="unique_hidevent"
)
]
db_table = "hidevent"
ordering = ("-timestamp",)

View File

@ -88,13 +88,13 @@ class Flag(BaseModel):
name = models.TextField(null=True, blank=True) name = models.TextField(null=True, blank=True)
type = models.CharField(max_length=6) type = models.CharField(max_length=6)
def __str__(self):
return f"{self.name} ({self.type})"
class Meta: class Meta:
db_table = "flag" db_table = "flag"
ordering = ("name",) ordering = ("name",)
def __str__(self):
return f"{self.name} ({self.type})"
class MemberQuerySet(models.QuerySet): class MemberQuerySet(models.QuerySet):
# TODO: maybe rename to reflect EXISTS? # TODO: maybe rename to reflect EXISTS?
@ -122,8 +122,6 @@ class MemberQuerySet(models.QuerySet):
# TODO: is this still a temporal table? # TODO: is this still a temporal table?
class Member(BaseModel): class Member(BaseModel):
objects = MemberQuerySet.as_manager()
uid = models.CharField(max_length=24, primary_key=True) uid = models.CharField(max_length=24, primary_key=True)
year_of_birth = models.TextField(db_column="Year of Birth", null=True, blank=True) year_of_birth = models.TextField(db_column="Year of Birth", null=True, blank=True)
account_name = models.TextField(db_column="Account Name", null=True, blank=True) account_name = models.TextField(db_column="Account Name", null=True, blank=True)
@ -264,8 +262,7 @@ class Member(BaseModel):
"Waiver form signed and on file date.": "%m/%d/%Y", "Waiver form signed and on file date.": "%m/%d/%Y",
} }
def __str__(self): objects = MemberQuerySet.as_manager()
return f"{self.account_name}"
class Meta: class Meta:
db_table = "members" db_table = "members"
@ -276,6 +273,9 @@ class Member(BaseModel):
models.Index(fields=["last_name"], name="last_name_idx"), models.Index(fields=["last_name"], name="last_name_idx"),
] ]
def __str__(self):
return f"{self.account_name}"
@classmethod @classmethod
def from_user(cls, user) -> "Member | None": def from_user(cls, user) -> "Member | None":
if hasattr(user, "ldap_user"): if hasattr(user, "ldap_user"):
@ -304,9 +304,6 @@ class MemberFlag(BaseModel):
) )
flag = models.ForeignKey(Flag, on_delete=models.PROTECT) flag = models.ForeignKey(Flag, on_delete=models.PROTECT)
def __str__(self):
return f"{self.member} - {self.flag}"
class Meta: class Meta:
db_table = "memberflag" db_table = "memberflag"
constraints = [ constraints = [
@ -315,6 +312,9 @@ class MemberFlag(BaseModel):
) )
] ]
def __str__(self):
return f"{self.member} - {self.flag}"
class Transaction(BaseModel): class Transaction(BaseModel):
sid = models.CharField(max_length=256, null=True, blank=True) sid = models.CharField(max_length=256, null=True, blank=True)
@ -364,24 +364,24 @@ class Transaction(BaseModel):
"_dp": None, "_dp": None,
} }
def __str__(self):
return f"{self.type} [{self.member if self.member else self.name}] {self.timestamp}"
class Meta: class Meta:
db_table = "transactions" db_table = "transactions"
def __str__(self):
return f"{self.type} [{self.member if self.member else self.name}] {self.timestamp}"
class EventCategory(models.Model): class EventCategory(models.Model):
id = models.IntegerField(primary_key=True) id = models.IntegerField(primary_key=True)
title = models.TextField() title = models.TextField()
def __str__(self):
return self.title
@classmethod @classmethod
def from_api_dict(cls, id: int, data): def from_api_dict(cls, id: int, data):
return cls(id=id, title=data["ttl"]) return cls(id=id, title=data["ttl"])
def __str__(self):
return self.title
class Event(BaseModel): class Event(BaseModel):
class EventCalendar(models.IntegerChoices): class EventCalendar(models.IntegerChoices):
@ -433,13 +433,13 @@ class Event(BaseModel):
_allowed_missing_fields = ["cap", "edp", "adn"] _allowed_missing_fields = ["cap", "edp", "adn"]
def __str__(self):
return self.unescaped_title
@property @property
def unescaped_title(self): def unescaped_title(self):
return nh3.clean(self.title, tags=set()) return nh3.clean(self.title, tags=set())
def __str__(self):
return self.unescaped_title
class EventInstructor(models.Model): class EventInstructor(models.Model):
name = models.TextField(blank=True) name = models.TextField(blank=True)
@ -526,8 +526,6 @@ class EventExtManager(models.Manager):
class EventExt(Event): class EventExt(Event):
"""Extension of `Event` to capture some fields not supported in MembershipWorks""" """Extension of `Event` to capture some fields not supported in MembershipWorks"""
objects = EventExtManager.from_queryset(EventExtQuerySet)()
instructor = models.ForeignKey( instructor = models.ForeignKey(
EventInstructor, on_delete=models.PROTECT, null=True, blank=True EventInstructor, on_delete=models.PROTECT, null=True, blank=True
) )
@ -557,6 +555,12 @@ class EventExt(Event):
should_survey = models.BooleanField(default=False) should_survey = models.BooleanField(default=False)
survey_email_sent = models.BooleanField(default=False) survey_email_sent = models.BooleanField(default=False)
objects = EventExtManager.from_queryset(EventExtQuerySet)()
class Meta:
verbose_name = "event"
ordering = ["-start"]
def get_absolute_url(self) -> str: def get_absolute_url(self) -> str:
return reverse("membershipworks:event-detail", kwargs={"eid": self.eid}) return reverse("membershipworks:event-detail", kwargs={"eid": self.eid})
@ -581,10 +585,6 @@ class EventExt(Event):
and getattr(self, "total_due_to_instructor") is not None and getattr(self, "total_due_to_instructor") is not None
) )
class Meta:
verbose_name = "event"
ordering = ["-start"]
if TYPE_CHECKING: if TYPE_CHECKING:

View File

@ -20,14 +20,14 @@ class AbstractAudit(models.Model):
good = models.BooleanField(default=False) good = models.BooleanField(default=False)
notes = models.CharField(max_length=255, blank=True) notes = models.CharField(max_length=255, blank=True)
def __str__(self) -> str:
return f"{'Good' if self.good else 'Bad'} audit at {self.date} by {self.user}"
class Meta: class Meta:
abstract = True abstract = True
ordering = ["date"] ordering = ["date"]
get_latest_by = ["date"] get_latest_by = ["date"]
def __str__(self) -> str:
return f"{'Good' if self.good else 'Bad'} audit at {self.date} by {self.user}"
class CmsRedRiverVeteransScholarship(models.Model): class CmsRedRiverVeteransScholarship(models.Model):
serial = models.AutoField(primary_key=True) serial = models.AutoField(primary_key=True)
@ -61,12 +61,12 @@ class CmsRedRiverVeteransScholarship(models.Model):
db_column="Program Status", max_length=16, blank=True, null=True db_column="Program Status", max_length=16, blank=True, null=True
) )
def __str__(self) -> str:
return f"{self.program_name} {self.member_name}"
class Meta: class Meta:
db_table = "CMS Red River Veterans Scholarship" db_table = "CMS Red River Veterans Scholarship"
def __str__(self) -> str:
return f"{self.program_name} {self.member_name}"
class DepartmentQuerySet(models.QuerySet): class DepartmentQuerySet(models.QuerySet):
def filter_by_shop_lead(self, member: Member) -> models.QuerySet["Department"]: def filter_by_shop_lead(self, member: Member) -> models.QuerySet["Department"]:
@ -80,8 +80,6 @@ class DepartmentQuerySet(models.QuerySet):
class Department(models.Model): class Department(models.Model):
objects = DepartmentQuerySet.as_manager()
name = models.CharField( name = models.CharField(
max_length=64, max_length=64,
validators=[RegexValidator("^[-_ A-Za-z0-9]*$")], validators=[RegexValidator("^[-_ A-Za-z0-9]*$")],
@ -101,6 +99,8 @@ class Department(models.Model):
) )
list_reply_to_address = models.EmailField(max_length=254, blank=True) list_reply_to_address = models.EmailField(max_length=254, blank=True)
objects = DepartmentQuerySet.as_manager()
def __str__(self) -> str: def __str__(self) -> str:
return self.name return self.name
@ -123,13 +123,13 @@ class CertificationDefinition(models.Model):
name = models.CharField(max_length=255) name = models.CharField(max_length=255)
department = models.ForeignKey(Department, models.PROTECT) department = models.ForeignKey(Department, models.PROTECT)
def __str__(self) -> str:
return f"{self.name} <{self.department}>"
class Meta: class Meta:
db_table = "Certification Definitions" db_table = "Certification Definitions"
ordering = ("name", "department") ordering = ("name", "department")
def __str__(self) -> str:
return f"{self.name} <{self.department}>"
def latest_version(self) -> "CertificationVersion": def latest_version(self) -> "CertificationVersion":
return self.certificationversion_set.latest() return self.certificationversion_set.latest()
@ -157,8 +157,6 @@ class CertificationVersionManager(models.Manager["CertificationVersion"]):
class CertificationVersion(models.Model): class CertificationVersion(models.Model):
objects = CertificationVersionManager()
definition = models.ForeignKey(CertificationDefinition, on_delete=models.PROTECT) definition = models.ForeignKey(CertificationDefinition, on_delete=models.PROTECT)
major = models.PositiveSmallIntegerField() major = models.PositiveSmallIntegerField()
minor = models.PositiveSmallIntegerField() minor = models.PositiveSmallIntegerField()
@ -166,8 +164,7 @@ class CertificationVersion(models.Model):
prerelease = models.CharField(max_length=255, blank=True) prerelease = models.CharField(max_length=255, blank=True)
approval_date = models.DateField(blank=True, null=True) approval_date = models.DateField(blank=True, null=True)
def __str__(self) -> str: objects = CertificationVersionManager()
return f"{self.definition} [{self.semantic_version()}]"
class Meta: class Meta:
constraints = [ constraints = [
@ -187,6 +184,9 @@ class CertificationVersion(models.Model):
get_latest_by = ("major", "minor", "patch", "prerelease", "approval_date") get_latest_by = ("major", "minor", "patch", "prerelease", "approval_date")
base_manager_name = "objects" base_manager_name = "objects"
def __str__(self) -> str:
return f"{self.definition} [{self.semantic_version()}]"
def semantic_version(self) -> VersionInfo: def semantic_version(self) -> VersionInfo:
return VersionInfo( return VersionInfo(
self.major or 0, self.major or 0,
@ -224,9 +224,6 @@ class Certification(models.Model):
shop_lead_notified = models.DateTimeField(blank=True, null=True) shop_lead_notified = models.DateTimeField(blank=True, null=True)
notes = models.CharField(max_length=255, blank=True, null=True) notes = models.CharField(max_length=255, blank=True, null=True)
def __str__(self) -> str:
return f"{self.name} - {self.certification_version}"
class Meta: class Meta:
db_table = "Certifications" db_table = "Certifications"
permissions = [ permissions = [
@ -236,6 +233,9 @@ class Certification(models.Model):
), ),
] ]
def __str__(self) -> str:
return f"{self.name} - {self.certification_version}"
class CertificationAudit(AbstractAudit): class CertificationAudit(AbstractAudit):
certification = models.ForeignKey( certification = models.ForeignKey(
@ -255,12 +255,12 @@ class InstructorOrVendor(models.Model):
db_column="email address", max_length=255, blank=True, null=True db_column="email address", max_length=255, blank=True, null=True
) )
def __str__(self) -> str:
return f"{self.name}"
class Meta: class Meta:
db_table = "Instructors and Vendors" db_table = "Instructors and Vendors"
def __str__(self) -> str:
return f"{self.name}"
class SpecialProgram(models.Model): class SpecialProgram(models.Model):
program_name = models.CharField( program_name = models.CharField(
@ -292,12 +292,12 @@ class SpecialProgram(models.Model):
db_column="Program Status", max_length=16, blank=True, null=True db_column="Program Status", max_length=16, blank=True, null=True
) )
def __str__(self) -> str:
return self.program_name
class Meta: class Meta:
db_table = "Special_Programs" db_table = "Special_Programs"
def __str__(self) -> str:
return self.program_name
class Waiver(models.Model): class Waiver(models.Model):
number = models.AutoField(db_column="Number", primary_key=True) number = models.AutoField(db_column="Number", primary_key=True)
@ -319,12 +319,12 @@ class Waiver(models.Model):
guardian_date = models.DateField(db_column="Guardian Date", blank=True, null=True) guardian_date = models.DateField(db_column="Guardian Date", blank=True, null=True)
notes = models.CharField(max_length=255, blank=True, null=True) notes = models.CharField(max_length=255, blank=True, null=True)
def __str__(self) -> str:
return f"{self.name} {self.date}"
class Meta: class Meta:
db_table = "Waivers" db_table = "Waivers"
def __str__(self) -> str:
return f"{self.name} {self.date}"
class WaiverAudit(AbstractAudit): class WaiverAudit(AbstractAudit):
waiver = models.ForeignKey(Waiver, on_delete=models.CASCADE, related_name="audits") waiver = models.ForeignKey(Waiver, on_delete=models.CASCADE, related_name="audits")

View File

@ -55,7 +55,7 @@ admin_email = "cmsmanage.django_q2_admin_email_reporter:AdminEmailReporter"
line-length = 88 line-length = 88
[tool.ruff.lint] [tool.ruff.lint]
select = ["E4", "E7", "E9", "F", "I", "C4", "UP", "PERF", "PL", "SIM", "FIX003"] select = ["E4", "E7", "E9", "F", "I", "C4", "UP", "PERF", "PL", "SIM", "FIX003", "DJ012"]
[tool.ruff.lint.isort] [tool.ruff.lint.isort]
known-first-party = [ known-first-party = [

View File

@ -33,17 +33,6 @@ class LockerUnit(models.Model):
rows = models.PositiveIntegerField(default=5) rows = models.PositiveIntegerField(default=5)
columns = models.PositiveIntegerField(default=2) columns = models.PositiveIntegerField(default=2)
def save(self, *args, **kwargs):
if self._state.adding:
# Create LockerInfo for each locker
with transaction.atomic():
super().save(self, *args, **kwargs)
for column in range(self.columns):
for row in range(self.rows):
self.lockers.create(column=column + 1, row=row + 1)
else:
super().save(self, *args, **kwargs)
class Meta: class Meta:
# TODO: add constraint to check for letter overlaps # TODO: add constraint to check for letter overlaps
constraints = [ constraints = [
@ -56,6 +45,17 @@ class LockerUnit(models.Model):
last_number = self.first_number + self.columns * self.rows last_number = self.first_number + self.columns * self.rows
return f"{self.bank.name} (Unit {last_letter}{self.first_number}-{self.first_letter}{last_number})" return f"{self.bank.name} (Unit {last_letter}{self.first_number}-{self.first_letter}{last_number})"
def save(self, *args, **kwargs):
if self._state.adding:
# Create LockerInfo for each locker
with transaction.atomic():
super().save(self, *args, **kwargs)
for column in range(self.columns):
for row in range(self.rows):
self.lockers.create(column=column + 1, row=row + 1)
else:
super().save(self, *args, **kwargs)
def letter_for_column(self, column: int) -> str: def letter_for_column(self, column: int) -> str:
return chr(column + ord(self.first_letter)) return chr(column + ord(self.first_letter))
@ -91,10 +91,6 @@ class LockerInfo(models.Model):
) )
notes = models.TextField(blank=True) notes = models.TextField(blank=True)
def clean(self):
if self.reserved and self.renter is not None:
raise ValidationError("Locker cannot both be reserved and rented!")
class Meta: class Meta:
constraints = [ constraints = [
models.UniqueConstraint( models.UniqueConstraint(
@ -106,6 +102,13 @@ class LockerInfo(models.Model):
), ),
] ]
def __str__(self):
return f"{self.locker_unit}-{self.address} [{self.renter}]"
def clean(self):
if self.reserved and self.renter is not None:
raise ValidationError("Locker cannot both be reserved and rented!")
@property @property
def available(self) -> bool: def available(self) -> bool:
return self.renter is None and not self.reserved return self.renter is None and not self.reserved
@ -132,6 +135,3 @@ class LockerInfo(models.Model):
) )
def address(self) -> str: def address(self) -> str:
return f"{self.letter}{self.number}" return f"{self.letter}{self.number}"
def __str__(self):
return f"{self.locker_unit}-{self.address} [{self.renter}]"

View File

@ -90,18 +90,18 @@ class GroupToolSubscription(SubscriptionSettings):
group = models.ForeignKey(Group, on_delete=models.CASCADE) group = models.ForeignKey(Group, on_delete=models.CASCADE)
tool = models.ForeignKey(Tool, on_delete=models.CASCADE) tool = models.ForeignKey(Tool, on_delete=models.CASCADE)
def get_task_subscriptions(self):
for task in self.tool.task_set.all():
yield GroupTaskSubscription(
days_before=self.days_before, group=self.group, task=task
)
class Meta: class Meta:
unique_together = (("group", "tool"),) unique_together = (("group", "tool"),)
def __str__(self): def __str__(self):
return f"{self.group}-{self.tool}, {super().__str__()}" return f"{self.group}-{self.tool}, {super().__str__()}"
def get_task_subscriptions(self):
for task in self.tool.task_set.all():
yield GroupTaskSubscription(
days_before=self.days_before, group=self.group, task=task
)
class GroupTaskSubscription(SubscriptionSettings): class GroupTaskSubscription(SubscriptionSettings):
group = models.ForeignKey(Group, on_delete=models.CASCADE) group = models.ForeignKey(Group, on_delete=models.CASCADE)
@ -110,6 +110,9 @@ class GroupTaskSubscription(SubscriptionSettings):
class Meta: class Meta:
unique_together = (("group", "task"),) unique_together = (("group", "task"),)
def __str__(self):
return f"{self.group}-{self.task}, {super().__str__()}"
@property @property
def should_remind(self): def should_remind(self):
next_recurrence = self.task.next_recurrence next_recurrence = self.task.next_recurrence
@ -118,9 +121,6 @@ class GroupTaskSubscription(SubscriptionSettings):
time_until_overdue = next_recurrence - datetime.datetime.now() time_until_overdue = next_recurrence - datetime.datetime.now()
return self.task.is_overdue or (time_until_overdue.days <= self.days_before) return self.task.is_overdue or (time_until_overdue.days <= self.days_before)
def __str__(self):
return f"{self.group}-{self.task}, {super().__str__()}"
class Event(models.Model): class Event(models.Model):
task = models.ForeignKey(Task, on_delete=models.CASCADE) task = models.ForeignKey(Task, on_delete=models.CASCADE)
@ -128,9 +128,9 @@ class Event(models.Model):
date = models.DateField() date = models.DateField()
notes = MarkdownxField(blank=True) notes = MarkdownxField(blank=True)
def __str__(self):
return f"{self.task}: {self.user} {self.date}"
@property @property
def notes_html(self): def notes_html(self):
return markdown_to_clean_html(self.notes) return markdown_to_clean_html(self.notes)
def __str__(self):
return f"{self.task}: {self.user} {self.date}"