Skip to content

Add initial implementations for result types and user events - #4

Merged
freefri merged 4 commits into
developfrom
feat/add-models-django
Apr 13, 2026
Merged

freefri merged 4 commits into
developfrom
feat/add-models-django

Conversation

@udernaeb

Copy link
Copy Markdown
Contributor

This pull request introduces two new Django apps, classes and clubs, along with their models, admin interfaces, and configuration. It also adds a reusable TimestampedModelAdmin base class for consistent handling of timestamp fields in the Django admin, and integrates this base admin into the new and existing apps. Additionally, the bcrypt package is added to the dependencies.

New app and model implementations:

  • Classes App:

    • Adds the apps/classes app with configuration (apps.py), empty URL routing (urls.py), and two models: Classes and ClassesControls, both inheriting from BaseUnmanagedModel. The models include foreign keys to related entities and custom string representations. ([[1]](https://github.com/oreplay/oreplay-python/pull/4/files#diff-1069263258a3876f3e3489cef17022e73c57419de816358750d4b0fe9c913a8cR1-R6), [[2]](https://github.com/oreplay/oreplay-python/pull/4/files#diff-78b7096c0805430dcd1bd3c4deaf618843288c71628f468d8f8cb09d42ca6840R1-R5), [[3]](https://github.com/oreplay/oreplay-python/pull/4/files#diff-eba775b94ad6ed660c5dc8c19f4813c2a01ed43e0f79fee27ba05917d6db5f9eR1-R85))
    • Registers both models in the Django admin using the new TimestampedModelAdmin, with customized display, search, and filter options. ([apps/classes/admin.pyR1-R43](https://github.com/oreplay/oreplay-python/pull/4/files#diff-8190b95abe3dc6fa4a21eab05b55e5f431b9e513b1b1c45e01446e1166ea2363R1-R43))
  • Clubs App:

    • Adds the apps/clubs app with configuration (apps.py), empty URL routing (urls.py), and a Clubs model with foreign keys and custom string representation. ([[1]](https://github.com/oreplay/oreplay-python/pull/4/files#diff-a7971a1ddd29c234966bcd4eecfbae7dda41c54e249ecefc8503965b4f39e82aR1-R6), [[2]](https://github.com/oreplay/oreplay-python/pull/4/files#diff-7d6ab8780deefa111aa7defea6123e76df18177dac8bad308b27681583a0508cR1-R5), [[3]](https://github.com/oreplay/oreplay-python/pull/4/files#diff-05d43b6fa289db89bdc080c7a86eddca0e8de36111cdfda204a9659c9d897de9R1-R30))
    • Registers the Clubs model in the Django admin using TimestampedModelAdmin, with customized list and filter options. ([apps/clubs/admin.pyR1-R23](https://github.com/oreplay/oreplay-python/pull/4/files#diff-7717250e234151128d922a2de0b241777c0ed3666fdcf1f466a723f4bacbad5bR1-R23))

Reusable admin improvements:

  • Shared Timestamped Admin:
    • Introduces TimestampedModelAdmin in apps/admin_base.py, a reusable base class for Django admin that automatically handles created, modified, and deleted fields as read-only and updates them appropriately on save and delete actions. This centralizes timestamp management for all models using this admin class. ([apps/admin_base.pyR1-R61](https://github.com/oreplay/oreplay-python/pull/4/files#diff-339f5750bf082a779854056bc3a8354e818d8737326baed13b4f69ea20b98b70R1-R61))

Other improvements:

  • Controls Admin Integration:
    • Updates the apps/controls/admin.py to use TimestampedModelAdmin for Controls and ControlTypes models, ensuring consistent timestamp handling and admin interface improvements. ([apps/controls/admin.pyR1-R24](https://github.com/oreplay/oreplay-python/pull/4/files#diff-718b8bbb17cdd3e0f48ad6fc187492527da01906bebcae824ad620d2e21d64d7R1-R24))

Dependency updates:

  • Pipfile:
    • Adds the bcrypt dependency, likely for password hashing or security enhancements. ([PipfileR16](https://github.com/oreplay/oreplay-python/pull/4/files#diff-230078d672f10d17463a8a6265cad825b790885898256a3365be90685caac58dR16))

…, teams, tokens, upload logs, and user events

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

This PR expands the Django project’s domain coverage by introducing a set of new “unmanaged” apps/models (to map existing DB tables) plus consistent Django admin handling for timestamp fields, and wires these apps into the base environment settings.

Changes:

  • Added multiple new Django apps (models + admin + app scaffolding) for events/structure/results/admin domains (e.g., classes, clubs, splits, tokens, etc.).
  • Introduced a reusable TimestampedModelAdmin and applied it across the new (and updated) admin registrations.
  • Updated settings/dependencies and local Docker compose configuration (custom user model setting + bcrypt dependency + compose env/network changes).

Reviewed changes

Copilot reviewed 74 out of 137 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
Pipfile Add bcrypt dependency
oreplay/environments/base.py Set AUTH_USER_MODEL, expand INSTALLED_APPS
docker-compose-python.yaml Use .env; adjust external network name
apps/admin_base.py Add TimestampedModelAdmin base admin
apps/shared_models.py Add BaseUnmanagedModel + verbose-name normalization
.gitignore Add negated patterns for apps/*
apps/usersevents/urls.py App URL scaffold (empty)
apps/usersevents/tests.py Test scaffold placeholder
apps/usersevents/models.py Add unmanaged UsersEvents model
apps/usersevents/migrations/init.py Migration package scaffold
apps/usersevents/apps.py AppConfig scaffold
apps/usersevents/admin.py Admin registration for UsersEvents
apps/usersevents/views.py Views scaffold placeholder
apps/usersevents/init.py Package scaffold
apps/users/models.py Custom User manager/auth helpers + bcrypt check
apps/users/apps.py Call unmanaged model name normalizer in ready()
apps/users/admin.py Register User/AccessToken with timestamped admin
apps/uploadlogs/urls.py App URL scaffold (empty)
apps/uploadlogs/tests.py Test scaffold placeholder
apps/uploadlogs/models.py Add unmanaged UploadLogs model
apps/uploadlogs/migrations/init.py Migration package scaffold
apps/uploadlogs/apps.py AppConfig scaffold
apps/uploadlogs/admin.py Admin registration for UploadLogs
apps/uploadlogs/views.py Views scaffold placeholder
apps/uploadlogs/init.py Package scaffold
apps/tokens/urls.py App URL scaffold (empty)
apps/tokens/tests.py Test scaffold placeholder
apps/tokens/models.py Add unmanaged Tokens model
apps/tokens/migrations/init.py Migration package scaffold
apps/tokens/apps.py AppConfig scaffold
apps/tokens/admin.py Admin registration for Tokens
apps/tokens/views.py Views scaffold placeholder
apps/tokens/init.py Package scaffold
apps/teams/urls.py App URL scaffold (empty)
apps/teams/tests.py Test scaffold placeholder
apps/teams/models.py Add unmanaged Teams + TeamResults models
apps/teams/migrations/init.py Migration package scaffold
apps/teams/apps.py AppConfig scaffold
apps/teams/admin.py Admin registrations for teams/results
apps/teams/views.py Views scaffold placeholder
apps/teams/init.py Package scaffold
apps/stages/urls.py App URL scaffold (empty)
apps/stages/tests.py Test scaffold placeholder
apps/stages/models.py Add unmanaged stage-related models
apps/stages/migrations/init.py Migration package scaffold
apps/stages/apps.py AppConfig scaffold
apps/stages/admin.py Admin registrations for stage models
apps/stages/views.py Views scaffold placeholder
apps/stages/init.py Package scaffold
apps/splits/urls.py App URL scaffold (empty)
apps/splits/tests.py Test scaffold placeholder
apps/splits/models.py Add unmanaged Splits model
apps/splits/migrations/init.py Migration package scaffold
apps/splits/apps.py AppConfig scaffold
apps/splits/admin.py Admin registration for Splits
apps/splits/views.py Views scaffold placeholder
apps/splits/init.py Package scaffold
apps/runners/urls.py App URL scaffold (empty)
apps/runners/tests.py Test scaffold placeholder
apps/runners/models.py Add unmanaged runners + results models
apps/runners/migrations/init.py Migration package scaffold
apps/runners/apps.py AppConfig scaffold
apps/runners/admin.py Admin registrations for runners/results
apps/runners/views.py Views scaffold placeholder
apps/runners/init.py Package scaffold
apps/resulttypes/urls.py App URL scaffold (empty)
apps/resulttypes/tests.py Test scaffold placeholder
apps/resulttypes/models.py Add unmanaged ResultTypes model
apps/resulttypes/migrations/init.py Migration package scaffold
apps/resulttypes/apps.py AppConfig scaffold
apps/resulttypes/admin.py Admin registration for ResultTypes
apps/resulttypes/views.py Views scaffold placeholder
apps/resulttypes/init.py Package scaffold
apps/rawuploads/urls.py App URL scaffold (empty)
apps/rawuploads/tests.py Test scaffold placeholder
apps/rawuploads/models.py Add unmanaged RawUploads model
apps/rawuploads/migrations/init.py Migration package scaffold
apps/rawuploads/apps.py AppConfig scaffold
apps/rawuploads/admin.py Admin registration for RawUploads
apps/rawuploads/views.py Views scaffold placeholder
apps/rawuploads/init.py Package scaffold
apps/rankings/views.py Views scaffold placeholder
apps/rankings/urls.py App URL scaffold (empty)
apps/rankings/tests.py Test scaffold placeholder
apps/rankings/models.py Add unmanaged Ranking model
apps/rankings/migrations/init.py Migration package scaffold
apps/rankings/apps.py AppConfig scaffold
apps/rankings/admin.py Admin registration for Ranking
apps/rankings/init.py Package scaffold
apps/federations/urls.py App URL scaffold (empty)
apps/federations/tests.py Test scaffold placeholder
apps/federations/models.py Add unmanaged Federations model
apps/federations/migrations/init.py Migration package scaffold
apps/federations/apps.py AppConfig scaffold
apps/federations/admin.py Admin registration for Federations
apps/federations/views.py Views scaffold placeholder
apps/federations/init.py Package scaffold
apps/events/urls.py App URL scaffold (empty)
apps/events/tests.py Test scaffold placeholder
apps/events/models.py Add unmanaged Events model
apps/events/migrations/init.py Migration package scaffold
apps/events/apps.py AppConfig scaffold
apps/events/admin.py Admin registration for Events
apps/events/views.py Views scaffold placeholder
apps/events/init.py Package scaffold
apps/courses/urls.py App URL scaffold (empty)
apps/courses/tests.py Test scaffold placeholder
apps/courses/models.py Add unmanaged Courses model
apps/courses/migrations/init.py Migration package scaffold
apps/courses/apps.py AppConfig scaffold
apps/courses/admin.py Admin registration for Courses
apps/courses/views.py Views scaffold placeholder
apps/courses/init.py Package scaffold
apps/controls/urls.py App URL scaffold (empty)
apps/controls/tests.py Test scaffold placeholder
apps/controls/models.py Add unmanaged controls-related models
apps/controls/migrations/init.py Migration package scaffold
apps/controls/apps.py AppConfig scaffold
apps/controls/admin.py Admin registrations for controls models
apps/controls/views.py Views scaffold placeholder
apps/controls/init.py Package scaffold
apps/clubs/urls.py App URL scaffold (empty)
apps/clubs/tests.py Test scaffold placeholder
apps/clubs/models.py Add unmanaged Clubs model
apps/clubs/migrations/init.py Migration package scaffold
apps/clubs/apps.py AppConfig scaffold
apps/clubs/admin.py Admin registration for Clubs
apps/clubs/views.py Views scaffold placeholder
apps/clubs/init.py Package scaffold
apps/classes/urls.py App URL scaffold (empty)
apps/classes/tests.py Test scaffold placeholder
apps/classes/models.py Add unmanaged classes-related models
apps/classes/migrations/init.py Migration package scaffold
apps/classes/apps.py AppConfig scaffold
apps/classes/admin.py Admin registrations for classes models
apps/classes/views.py Views scaffold placeholder
apps/classes/init.py Package scaffold

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread apps/splits/admin.py
Comment on lines +26 to +30
"runner_result",
"team_result",
"class_",
"control",
]
Comment thread apps/splits/admin.py
"reading_time",
"created",
]
search_fields = ["sicard", "station"]
Comment thread apps/controls/admin.py
Comment on lines +18 to +20
list_display = ["id", "event", "stage", "station", "control_type", "created"]
search_fields = ["station"]
list_filter = ["event", "stage", "control_type"]
Comment thread apps/classes/admin.py
Comment on lines +36 to +39
"created",
]
search_fields = ["order_number"]
list_filter = ["event", "stage", "order_number"]
Comment thread apps/usersevents/admin.py
Comment on lines +9 to +11
list_display = ["user", "event", "created"]
search_fields = ["user__username", "event__description"]
list_filter = ["event"]
Comment on lines 13 to 15
env_file:
- .env.example
- .env
extra_hosts:
…ry_class' for consistency across classes, runners, splits, teams, and rankings. Add scoring_algorithm field to Ranking model.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

This PR expands the project’s domain model by introducing a shared unmanaged-model foundation plus a reusable Django admin base for timestamp handling, and then scaffolds a large set of new “read-only/unmanaged” apps (events/structure/results/admin-related entities). It also switches the project to a custom users.User auth model and adds bcrypt for legacy password verification.

Changes:

  • Add TimestampedModelAdmin and BaseUnmanagedModel/naming normalization helpers to standardize admin + unmanaged model behavior.
  • Introduce many new Django apps with unmanaged models + admin registrations (events, stages, courses, controls, classes, clubs, teams, runners, splits, tokens, uploadlogs, rawuploads, rankings, user-event links, etc.).
  • Configure AUTH_USER_MODEL and enhance users.User with a custom manager and bcrypt-compatible password checking.

Reviewed changes

Copilot reviewed 74 out of 137 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
Pipfile Adds bcrypt dependency (lockfile update needed).
oreplay/environments/base.py Sets AUTH_USER_MODEL and expands/reorders INSTALLED_APPS.
docker-compose-python.yaml Uses .env for env_file and renames the external network.
.gitignore Adds explicit tracking exceptions for new apps/* modules.
apps/admin_base.py Introduces TimestampedModelAdmin for consistent timestamp fields behavior in Django admin.
apps/shared_models.py Adds BaseUnmanagedModel (+ stage-scoped base) and verbose-name normalization for unmanaged models.
apps/users/models.py Implements UserManager, adds bcrypt-aware check_password, and auth-related properties on User.
apps/users/apps.py Calls unmanaged model verbose-name normalization at app startup.
apps/users/admin.py Registers User and AccessToken using TimestampedModelAdmin.
apps/classes/urls.py Adds empty URLConf scaffold for classes.
apps/classes/models.py Adds unmanaged Classes and ClassesControls models.
apps/classes/apps.py Adds app config for classes.
apps/classes/admin.py Registers Classes and ClassesControls in admin.
apps/clubs/urls.py Adds empty URLConf scaffold for clubs.
apps/clubs/models.py Adds unmanaged Clubs model.
apps/clubs/apps.py Adds app config for clubs.
apps/clubs/admin.py Registers Clubs in admin.
apps/controls/urls.py Adds empty URLConf scaffold for controls.
apps/controls/models.py Adds unmanaged Controls and ControlTypes models.
apps/controls/apps.py Adds app config for controls.
apps/controls/admin.py Registers Controls/ControlTypes in admin using shared timestamp admin.
apps/courses/urls.py Adds empty URLConf scaffold for courses.
apps/courses/models.py Adds unmanaged Courses model.
apps/courses/apps.py Adds app config for courses.
apps/courses/admin.py Registers Courses in admin.
apps/events/urls.py Adds empty URLConf scaffold for events.
apps/events/models.py Adds unmanaged Events model.
apps/events/apps.py Adds app config for events.
apps/events/admin.py Registers Events in admin.
apps/federations/urls.py Adds empty URLConf scaffold for federations.
apps/federations/models.py Adds unmanaged Federations model.
apps/federations/apps.py Adds app config for federations.
apps/federations/admin.py Registers Federations in admin.
apps/stages/urls.py Adds empty URLConf scaffold for stages.
apps/stages/models.py Adds unmanaged Stages, StageTypes, StageOrders models.
apps/stages/apps.py Adds app config for stages.
apps/stages/admin.py Registers stage models in admin.
apps/teams/urls.py Adds empty URLConf scaffold for teams.
apps/teams/models.py Adds unmanaged Teams and TeamResults models.
apps/teams/apps.py Adds app config for teams.
apps/teams/admin.py Registers team models in admin.
apps/runners/urls.py Adds empty URLConf scaffold for runners.
apps/runners/models.py Adds unmanaged Runners and RunnerResults models.
apps/runners/apps.py Adds app config for runners.
apps/runners/admin.py Registers runner models in admin.
apps/resulttypes/urls.py Adds empty URLConf scaffold for resulttypes.
apps/resulttypes/models.py Adds unmanaged ResultTypes model.
apps/resulttypes/apps.py Adds app config for resulttypes.
apps/resulttypes/admin.py Registers ResultTypes in admin.
apps/splits/urls.py Adds empty URLConf scaffold for splits.
apps/splits/models.py Adds unmanaged Splits model.
apps/splits/apps.py Adds app config for splits.
apps/splits/admin.py Registers Splits in admin.
apps/tokens/urls.py Adds empty URLConf scaffold for tokens.
apps/tokens/models.py Adds unmanaged Tokens model.
apps/tokens/apps.py Adds app config for tokens.
apps/tokens/admin.py Registers Tokens in admin.
apps/uploadlogs/urls.py Adds empty URLConf scaffold for uploadlogs.
apps/uploadlogs/models.py Adds unmanaged UploadLogs model.
apps/uploadlogs/apps.py Adds app config for uploadlogs.
apps/uploadlogs/admin.py Registers UploadLogs in admin.
apps/rawuploads/urls.py Adds empty URLConf scaffold for rawuploads.
apps/rawuploads/models.py Adds unmanaged RawUploads model.
apps/rawuploads/apps.py Adds app config for rawuploads.
apps/rawuploads/admin.py Registers RawUploads in admin.
apps/rankings/views.py Adds placeholder views module for rankings.
apps/rankings/urls.py Adds empty URLConf scaffold for rankings.
apps/rankings/tests.py Adds placeholder tests module for rankings.
apps/rankings/models.py Adds unmanaged Ranking model.
apps/rankings/apps.py Adds app config for rankings.
apps/rankings/admin.py Registers Ranking in admin.
apps/usersevents/urls.py Adds empty URLConf scaffold for usersevents.
apps/usersevents/models.py Adds unmanaged UsersEvents join model.
apps/usersevents/apps.py Adds app config for usersevents.
apps/usersevents/admin.py Registers UsersEvents in admin.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread Pipfile
Comment on lines 14 to 17
django-cors-headers = "==4.9.0" # Manejo de CORS (actualizado)
drf-spectacular = "*"
bcrypt = "*"
setuptools = "==82.0.1"

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.

Comment thread docker-compose-python.yaml
Comment thread apps/usersevents/admin.py
Comment on lines +8 to +11
class UsersEventsAdmin(TimestampedModelAdmin):
list_display = ["user", "event", "created"]
search_fields = ["user__username", "event__description"]
list_filter = ["event"]

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 588fc8c. Changed user__username to user__email in search_fields since username is only a Python @property on the User model (not a database field), which would cause a FieldError in admin search.

Comment thread apps/users/models.py
Comment on lines +18 to +26
def create_user(self, email, password=None, **extra_fields):
if not email:
raise ValueError("The email field is required")
email = self.normalize_email(email)
user = self.model(email=email, **extra_fields)
if password:
user.set_password(password)
user.save(using=self._db)
return user
Comment thread oreplay/environments/base.py
@sonarqubecloud

Copy link
Copy Markdown

@freefri freefri left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

blindly approve

@freefri
freefri merged commit 30c553b into develop Apr 13, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants