Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -176,5 +176,38 @@ cython_debug/
# Ignore the results/ directory if it contains generated files or outputs that should not be committed to version control.
results/

# Exceptions for new apps - all apps should be tracked
!apps/classes/
!apps/classes/**
!apps/clubs/
!apps/clubs/**
!apps/controls/
!apps/controls/**
!apps/courses/
!apps/courses/**
!apps/events/
!apps/events/**
!apps/federations/
!apps/federations/**
!apps/rawuploads/
!apps/rawuploads/**
!apps/resulttypes/
!apps/resulttypes/**
!apps/runners/
!apps/runners/**
!apps/splits/
!apps/splits/**
!apps/stages/
!apps/stages/**
!apps/teams/
!apps/teams/**
!apps/tokens/
!apps/tokens/**
!apps/uploadlogs/
!apps/uploadlogs/**
!apps/usersevents/
!apps/usersevents/**
!apps/shared_models.py

# Ignore the requirements.txt file if it contains sensitive information such as private package indexes or credentials.
requirements.txt
1 change: 1 addition & 0 deletions Pipfile
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ mysqlclient = "2.2" # Soporte para MySQL
python-decouple = "3.8" # Gestión de variables de entorno
django-cors-headers = "==4.9.0" # Manejo de CORS (actualizado)
drf-spectacular = "*"
bcrypt = "*"
setuptools = "==82.0.1"
Comment on lines 14 to 17

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot apply changes based on this feedback

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in commit 5bd3dac. Regenerated Pipfile.lock — bcrypt is now included in the default section with pinned hashes for consistent installs.

wheel = "==0.46.3"

Expand Down
90 changes: 80 additions & 10 deletions Pipfile.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

61 changes: 61 additions & 0 deletions apps/admin_base.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
from django.contrib import admin
from django.utils import timezone


class TimestampedModelAdmin(admin.ModelAdmin):
timestamp_fields = ("created", "modified", "deleted")

def get_readonly_fields(self, request, obj=None):
readonly_fields = list(super().get_readonly_fields(request, obj))
for field_name in self.timestamp_fields:
if (
field_name in {field.name for field in self.model._meta.fields}
and field_name not in readonly_fields
):
readonly_fields.append(field_name)
return readonly_fields

def save_model(self, request, obj, form, change):
now = timezone.now()
field_names = {field.name for field in self.model._meta.fields}

if (
"created" in field_names
and not change
and getattr(obj, "created", None) is None
):
obj.created = now
if "modified" in field_names:
obj.modified = now
if "deleted" in field_names and getattr(obj, "deleted", None) is None:
obj.deleted = None

super().save_model(request, obj, form, change)

def delete_model(self, request, obj):
field_names = {field.name for field in self.model._meta.fields}
if "deleted" in field_names:
now = timezone.now()
obj.deleted = now
if "modified" in field_names:
obj.modified = now
obj.save(
update_fields=[
field for field in ("deleted", "modified") if field in field_names
]
)
return

super().delete_model(request, obj)

def delete_queryset(self, request, queryset):
field_names = {field.name for field in self.model._meta.fields}
if "deleted" in field_names:
now = timezone.now()
update_fields = {"deleted": now}
if "modified" in field_names:
update_fields["modified"] = now
queryset.update(**update_fields)
return

super().delete_queryset(request, queryset)
Empty file added apps/classes/__init__.py
Empty file.
42 changes: 42 additions & 0 deletions apps/classes/admin.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
from apps.admin_base import TimestampedModelAdmin
from django.contrib import admin

from .models import Classes, ClassesControls


@admin.register(Classes)
class ClassesAdmin(TimestampedModelAdmin):
list_display = [
"id",
"event",
"stage",
"short_name",
"long_name",
"oe_key",
"course",
"created",
]
search_fields = ["short_name", "long_name", "oe_key"]
list_filter = ["event", "stage"]
list_select_related = ["event", "stage", "course"]
list_per_page = 50
show_full_result_count = False
ordering = ["-created"]


@admin.register(ClassesControls)
class ClassesControlsAdmin(TimestampedModelAdmin):
list_display = [
"event",
"stage",
"control_class",
"control",
"order_number",
"created",
]
search_fields = ["order_number"]
list_filter = ["event", "stage", "order_number"]
Comment on lines +35 to +38
list_select_related = ["event", "stage", "control_class", "control"]
list_per_page = 50
show_full_result_count = False
ordering = ["-created"]
6 changes: 6 additions & 0 deletions apps/classes/apps.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
from django.apps import AppConfig


class ClassesConfig(AppConfig):
default_auto_field = "django.db.models.BigAutoField"
name = "apps.classes"
Empty file.
81 changes: 81 additions & 0 deletions apps/classes/models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
from apps.shared_models import BaseUnmanagedModel
from django.db import models


class Classes(BaseUnmanagedModel):
event = models.ForeignKey(
"events.Events",
on_delete=models.DO_NOTHING,
db_column="event_id",
null=True,
blank=True,
related_name="classes_rows",
)
stage = models.ForeignKey(
"stages.Stages",
on_delete=models.DO_NOTHING,
db_column="stage_id",
null=True,
blank=True,
related_name="classes_rows",
)
oe_key = models.CharField(max_length=50, null=True, blank=True)
short_name = models.CharField(max_length=100, null=True, blank=True)
long_name = models.CharField(max_length=255, null=True, blank=True)
course = models.ForeignKey(
"courses.Courses",
on_delete=models.DO_NOTHING,
db_column="course_id",
null=True,
blank=True,
related_name="classes_rows",
)
upload_hash = models.CharField(max_length=255, null=True, blank=True)

class Meta(BaseUnmanagedModel.Meta):
db_table = "classes"

def __str__(self):
return self.short_name or self.long_name or f"Class {self.id}"


class ClassesControls(BaseUnmanagedModel):
id = None
event = models.ForeignKey(
"events.Events",
on_delete=models.DO_NOTHING,
db_column="event_id",
null=True,
blank=True,
related_name="classes_controls_rows",
)
stage = models.ForeignKey(
"stages.Stages",
on_delete=models.DO_NOTHING,
db_column="stage_id",
null=True,
blank=True,
related_name="classes_controls_rows",
)
control_class = models.ForeignKey(
"Classes",
on_delete=models.DO_NOTHING,
db_column="class_id",
primary_key=True,
related_name="classes_controls_rows",
)
control = models.ForeignKey(
"controls.Controls",
on_delete=models.DO_NOTHING,
db_column="control_id",
null=True,
blank=True,
related_name="classes_controls_rows",
)
order_number = models.IntegerField(null=True, blank=True)

class Meta(BaseUnmanagedModel.Meta):
db_table = "classes_controls"

def __str__(self):
return f"ClassControl {self.control_class_id}:{self.control_id}:{self.order_number}"
Empty file added apps/classes/tests.py
Empty file.
5 changes: 5 additions & 0 deletions apps/classes/urls.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
from django.urls import path

app_name = "classes"

urlpatterns = []
Empty file added apps/classes/views.py
Empty file.
Empty file added apps/clubs/__init__.py
Empty file.
23 changes: 23 additions & 0 deletions apps/clubs/admin.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
from apps.admin_base import TimestampedModelAdmin
from django.contrib import admin

from .models import Clubs


@admin.register(Clubs)
class ClubsAdmin(TimestampedModelAdmin):
list_display = [
"id",
"short_name",
"long_name",
"oe_key",
"event",
"stage",
"created",
]
search_fields = ["short_name", "long_name", "oe_key"]
list_filter = ["event", "stage"]
list_select_related = ["event", "stage"]
list_per_page = 50
show_full_result_count = False
ordering = ["-created"]
Loading
Loading