Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
b7a0a53
Configure MailHog with authentication and email settings
shorodilov Dec 7, 2025
b206e0c
Specify full image path for PostgreSQL in compose.yaml
shorodilov Dec 7, 2025
b8bcb54
build: update dependencies to latest versions
shorodilov Dec 9, 2025
af21c8f
build: update auto-assign configuration and workflow
shorodilov Dec 9, 2025
dc58c12
build: update dependencies and add `bumpver`
shorodilov Dec 9, 2025
68458b2
bump version 2025.10 -> 2025.1011dev0
shorodilov Dec 9, 2025
40c8844
ci: update Python version format in workflow
shorodilov Dec 9, 2025
76d299c
ci: remove auto-assign workflow and configuration
shorodilov Dec 9, 2025
be60144
ci: update github actions (#9)
shorodilov Dec 9, 2025
a7b9e8a
build: add bumpver package for version handling (#7)
shorodilov Dec 9, 2025
f1989d0
bump version 2025.1011dev0 -> 2025.1012rc0
shorodilov Dec 9, 2025
cd76644
feat: update SMTP dev container (#8)
shorodilov Dec 9, 2025
612efc7
Merge branch 'release/2025.1011' into feature/dependencies
shorodilov Dec 9, 2025
f5d644b
build: update dependencies to latest versions (#6)
shorodilov Dec 9, 2025
d0d62ce
build: update versioning pattern in bumpver config
shorodilov Dec 9, 2025
f78d010
bump version 2025.10rc1 -> 2025.12rc0
shorodilov Dec 9, 2025
abcd652
[GH-10] feat: add a custom user model and configuration
shorodilov Dec 10, 2025
e165dee
[GH-11] feat: correct `STATIC_URL` to use full localhost URL
shorodilov Dec 10, 2025
31ab226
[GH-11] feat: correct `STATIC_URL` to use full localhost URL (#12)
shorodilov Dec 10, 2025
831fe16
[GH-10] feat: add a custom user model and configuration (#13)
shorodilov Dec 10, 2025
8cad3e4
[GH-11] fix: add missing trailing slash in `STATIC_URL`
shorodilov Dec 10, 2025
b15de8e
refactor: rename `project_core` to `website` across the project
shorodilov Dec 10, 2025
78b2d4c
[GH-14] feat: configure Black formatting rules in pyproject.toml
shorodilov Dec 10, 2025
166ae08
[black] fix: clean up formatting in initial user migration and settings
shorodilov Dec 10, 2025
b134d0f
[GH-14] Set up black (#15)
shorodilov Dec 10, 2025
cf766b3
bump version 2025.12rc0 -> 2025.12rc1
shorodilov Dec 10, 2025
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
12 changes: 0 additions & 12 deletions .github/auto-assign.yml

This file was deleted.

18 changes: 0 additions & 18 deletions .github/workflows/auto-assign.yml

This file was deleted.

2 changes: 1 addition & 1 deletion .github/workflows/run-linters.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ jobs:
- name: Set up Python
uses: actions/setup-python@v2
with:
python-version: 3.10
python-version: "3.10"

- name: Install dependencies
run: |
Expand Down
6 changes: 5 additions & 1 deletion containers/compose.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name: django-tpl
services:
database:
image: postgres:16.10-alpine
image: docker.io/postgres:16.10-alpine
container_name: postgres
restart: unless-stopped
environment:
Expand All @@ -18,6 +18,10 @@ services:
ports:
- "${SMTP_PORT:-1025}:1025"
- "${SMTP_WEB_PORT:-8025}:8025"
volumes:
- ./mailhog:/etc/mailhog:ro
environment:
- MH_AUTH_FILE=/etc/mailhog/auth.txt

staticfiles:
image: docker.io/caddy:2.10.2-alpine
Expand Down
1 change: 1 addition & 0 deletions containers/mailhog/auth.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
django:$2a$12$cWb4JgyAwd9BoD.4sr6mOuSg9/1vTq6JUYRZfCjSgJJmTtG3rz1FC
27 changes: 24 additions & 3 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,31 @@ dependencies = [
"psycopg[binary]",
]

[project.optional-dependencies]
[dependency-groups]
dev = [
"pytest-django",
"black>=25.9.0",
"bumpver>=2025.1131",
"pytest-django>=4.11.1",
]

[project.urls]
[tool.bumpver]
current_version = "2025.12rc1"
version_pattern = "YYYY.0M[.PATCH][PYTAGNUM]"
commit_message = "bump version {old_version} -> {new_version}"
tag_message = "{new_version}"
tag_scope = "default"
pre_commit_hook = ""
post_commit_hook = ""
commit = true
tag = true
push = false

[tool.bumpver.file_patterns]
"pyproject.toml" = [
'current_version = "{version}"',
]

[tool.black]
line-length = 119
target-version = ["py310", "py311", "py312"]
include = "\\.pyi?$"
2 changes: 1 addition & 1 deletion src/manage.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

def main():
"""Run administrative tasks."""
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "project_core.settings")
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "website.settings")
try:
from django.core.management import execute_from_command_line
except ImportError as exc:
Expand Down
File renamed without changes.
5 changes: 5 additions & 0 deletions src/user/admin.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
from django.contrib import admin
from django.contrib.auth.admin import UserAdmin
from .models import User

admin.site.register(User, UserAdmin)
5 changes: 5 additions & 0 deletions src/user/apps.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
from django.apps import AppConfig


class UserConfig(AppConfig):
name = "user"
Copy link

Copilot AI Jan 11, 2026

Choose a reason for hiding this comment

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

The AppConfig class is missing the default_auto_field attribute. While this will work, Django best practices recommend explicitly setting this to avoid migration warnings. Consider adding default_auto_field = "django.db.models.BigAutoField" to match the project's DEFAULT_AUTO_FIELD setting.

Suggested change
name = "user"
name = "user"
default_auto_field = "django.db.models.BigAutoField"

Copilot uses AI. Check for mistakes.
120 changes: 120 additions & 0 deletions src/user/migrations/0001_initial.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
# Generated by Django 6.0 on 2025-12-10 08:53

import django.contrib.auth.models
import django.contrib.auth.validators
import django.utils.timezone
from django.db import migrations, models


class Migration(migrations.Migration):

initial = True

dependencies = [
("auth", "0012_alter_user_first_name_max_length"),
]

operations = [
migrations.CreateModel(
name="User",
fields=[
(
"id",
models.BigAutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
("password", models.CharField(max_length=128, verbose_name="password")),
(
"last_login",
models.DateTimeField(blank=True, null=True, verbose_name="last login"),
),
(
"is_superuser",
models.BooleanField(
default=False,
help_text="Designates that this user has all permissions without explicitly assigning them.",
verbose_name="superuser status",
),
),
(
"username",
models.CharField(
error_messages={"unique": "A user with that username already exists."},
help_text="Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only.",
max_length=150,
unique=True,
validators=[django.contrib.auth.validators.UnicodeUsernameValidator()],
verbose_name="username",
),
),
(
"first_name",
models.CharField(blank=True, max_length=150, verbose_name="first name"),
),
(
"last_name",
models.CharField(blank=True, max_length=150, verbose_name="last name"),
),
(
"email",
models.EmailField(blank=True, max_length=254, verbose_name="email address"),
),
(
"is_staff",
models.BooleanField(
default=False,
help_text="Designates whether the user can log into this admin site.",
verbose_name="staff status",
),
),
(
"is_active",
models.BooleanField(
default=True,
help_text="Designates whether this user should be treated as active. "
"Unselect this instead of deleting accounts.",
verbose_name="active",
),
),
(
"date_joined",
models.DateTimeField(default=django.utils.timezone.now, verbose_name="date joined"),
),
(
"groups",
models.ManyToManyField(
blank=True,
help_text="The groups this user belongs to. A user will get all permissions granted "
"to each of their groups.",
related_name="user_set",
related_query_name="user",
to="auth.group",
verbose_name="groups",
),
),
(
"user_permissions",
models.ManyToManyField(
blank=True,
help_text="Specific permissions for this user.",
related_name="user_set",
related_query_name="user",
to="auth.permission",
verbose_name="user permissions",
),
),
],
options={
"verbose_name": "user",
"verbose_name_plural": "users",
"abstract": False,
},
managers=[
("objects", django.contrib.auth.models.UserManager()),
],
),
]
Empty file added src/user/migrations/__init__.py
Empty file.
15 changes: 15 additions & 0 deletions src/user/models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
"""
Custom user model

.. seealso::
https://docs.djangoproject.com/en/dev/topics/auth/customizing/
https://docs.djangoproject.com/en/5.2/topics/auth/customizing/#substituting-a-custom-user-model
https://docs.djangoproject.com/en/5.2/topics/auth/customizing/#referencing-the-user-model

"""

from django.contrib.auth.models import AbstractUser


class User(AbstractUser):
pass
Copy link

Copilot AI Jan 11, 2026

Choose a reason for hiding this comment

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

The User model class is missing a docstring. While it currently only inherits from AbstractUser without modifications, it's a best practice to document the purpose and intended use of custom user models, especially as they typically grow to include custom fields and methods.

Suggested change
pass
"""Custom user model for this project, extending Django's ``AbstractUser``.
This class currently does not add any additional fields or behavior, but
serves as the central place to define project-specific user-related
functionality (e.g., extra profile fields, custom managers, or methods).
"""

Copilot uses AI. Check for mistakes.
Empty file added src/website/__init__.py
Empty file.
2 changes: 1 addition & 1 deletion src/project_core/asgi.py → src/website/asgi.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,6 @@

from django.core.asgi import get_asgi_application

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "project_core.settings")
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "website.settings")

application = get_asgi_application()
22 changes: 19 additions & 3 deletions src/project_core/settings.py → src/website/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
# See https://docs.djangoproject.com/en/5.2/howto/deployment/checklist/

# SECURITY WARNING: keep the secret key used in production secret!
# noinspection SpellCheckingInspection
SECRET_KEY = "django-insecure-ir1a1f!bjywcs+1$shmpbq=6ss3!0!^%tha*midcv=mn*48x^f"

# SECURITY WARNING: don't run with debug turned on in production!
Expand All @@ -37,6 +38,7 @@
"django.contrib.sessions",
"django.contrib.messages",
"django.contrib.staticfiles",
"user.apps.UserConfig",
]

MIDDLEWARE = [
Expand All @@ -49,7 +51,7 @@
"django.middleware.clickjacking.XFrameOptionsMiddleware",
]

ROOT_URLCONF = "project_core.urls"
ROOT_URLCONF = "website.urls"

TEMPLATES = [
{
Expand All @@ -66,7 +68,7 @@
},
]

WSGI_APPLICATION = "project_core.wsgi.application"
WSGI_APPLICATION = "website.wsgi.application"


# Database
Expand Down Expand Up @@ -121,10 +123,24 @@
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/5.2/howto/static-files/

STATIC_URL = "static/"
STATIC_URL = "http://localhost:8888/"
STATIC_ROOT = BASE_DIR.parent / "staticfiles"

# Default primary key field type
# https://docs.djangoproject.com/en/5.2/ref/settings/#default-auto-field

DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField"

# Sending email
# https://docs.djangoproject.com/en/5.2/topics/email/

EMAIL_HOST = "localhost"
EMAIL_PORT = 1025
EMAIL_HOST_USER = "django"
EMAIL_HOST_PASSWORD = "django"
EMAIL_SUBJECT_PREFIX = ""

# Custom user model
# https://docs.djangoproject.com/en/5.2/topics/auth/customizing/

AUTH_USER_MODEL = "user.User"
File renamed without changes.
2 changes: 1 addition & 1 deletion src/project_core/wsgi.py → src/website/wsgi.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,6 @@

from django.core.wsgi import get_wsgi_application

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "project_core.settings")
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "website.settings")

application = get_wsgi_application()
Loading
Loading