commit
4d33f49082
29 changed files with 427 additions and 0 deletions
@ -0,0 +1,72 @@ |
|||||
|
# Python compiled files |
||||
|
__pycache__/ |
||||
|
*.py[cod] |
||||
|
*$py.class |
||||
|
|
||||
|
# Django specific |
||||
|
*.log |
||||
|
*.pot |
||||
|
*.pyc |
||||
|
*.sqlite3 |
||||
|
db.sqlite3 |
||||
|
media/ |
||||
|
staticfiles/ |
||||
|
.env |
||||
|
.env.* |
||||
|
|
||||
|
# Distribution / packaging |
||||
|
*.egg |
||||
|
*.egg-info/ |
||||
|
dist/ |
||||
|
build/ |
||||
|
eggs/ |
||||
|
parts/ |
||||
|
bin/ |
||||
|
var/ |
||||
|
sdist/ |
||||
|
develop-eggs/ |
||||
|
|
||||
|
# PyInstaller |
||||
|
*.manifest |
||||
|
*.spec |
||||
|
|
||||
|
# Unit test / coverage reports |
||||
|
htmlcov/ |
||||
|
.tox/ |
||||
|
.nox/ |
||||
|
.coverage |
||||
|
.coverage.* |
||||
|
.cache |
||||
|
nosetests.xml |
||||
|
coverage.xml |
||||
|
*.cover |
||||
|
*.py,cover |
||||
|
.hypothesis/ |
||||
|
.pytest_cache/ |
||||
|
|
||||
|
# Translations |
||||
|
*.mo |
||||
|
*.pot |
||||
|
|
||||
|
# Django stuff: |
||||
|
local_settings.py |
||||
|
db.sqlite3 |
||||
|
media/ |
||||
|
|
||||
|
# IDEs and editors |
||||
|
.vscode/ |
||||
|
.idea/ |
||||
|
*.sublime-project |
||||
|
*.sublime-workspace |
||||
|
*.iml |
||||
|
*.ipr |
||||
|
*.iws |
||||
|
|
||||
|
# macOS |
||||
|
.DS_Store |
||||
|
|
||||
|
# Windows |
||||
|
Thumbs.db |
||||
|
|
||||
|
# Venv |
||||
|
venv/ |
||||
@ -0,0 +1,6 @@ |
|||||
|
from django.contrib import admin |
||||
|
from .models import DiveBase |
||||
|
|
||||
|
@admin.register(DiveBase) |
||||
|
class DiveBaseAdmin(admin.ModelAdmin): |
||||
|
list_display = ("name", "location") |
||||
@ -0,0 +1,22 @@ |
|||||
|
# Generated by Django 5.2.9 on 2026-01-06 11:46 |
||||
|
|
||||
|
from django.db import migrations, models |
||||
|
|
||||
|
|
||||
|
class Migration(migrations.Migration): |
||||
|
|
||||
|
initial = True |
||||
|
|
||||
|
dependencies = [ |
||||
|
] |
||||
|
|
||||
|
operations = [ |
||||
|
migrations.CreateModel( |
||||
|
name='DiveBase', |
||||
|
fields=[ |
||||
|
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), |
||||
|
('name', models.CharField(max_length=255)), |
||||
|
('location', models.CharField(max_length=255)), |
||||
|
], |
||||
|
), |
||||
|
] |
||||
@ -0,0 +1,6 @@ |
|||||
|
|
||||
|
from django.db import models |
||||
|
|
||||
|
class DiveBase(models.Model): |
||||
|
name = models.CharField(max_length=255) |
||||
|
location = models.CharField(max_length=255) |
||||
@ -0,0 +1,59 @@ |
|||||
|
|
||||
|
from pathlib import Path |
||||
|
|
||||
|
BASE_DIR = Path(__file__).resolve().parent.parent |
||||
|
|
||||
|
SECRET_KEY = 'dev-secret-key' |
||||
|
DEBUG = True |
||||
|
ALLOWED_HOSTS = [] |
||||
|
|
||||
|
INSTALLED_APPS = [ |
||||
|
'users', |
||||
|
'django.contrib.admin', |
||||
|
'django.contrib.auth', |
||||
|
'django.contrib.contenttypes', |
||||
|
'django.contrib.sessions', |
||||
|
'django.contrib.messages', |
||||
|
'django.contrib.staticfiles', |
||||
|
'rest_framework', |
||||
|
'divebases', |
||||
|
'events', |
||||
|
'infos', |
||||
|
] |
||||
|
|
||||
|
AUTH_USER_MODEL = 'users.User' |
||||
|
|
||||
|
MIDDLEWARE = [ |
||||
|
'django.middleware.security.SecurityMiddleware', |
||||
|
'django.contrib.sessions.middleware.SessionMiddleware', |
||||
|
'django.middleware.common.CommonMiddleware', |
||||
|
'django.middleware.csrf.CsrfViewMiddleware', |
||||
|
'django.contrib.auth.middleware.AuthenticationMiddleware', |
||||
|
'django.contrib.messages.middleware.MessageMiddleware', |
||||
|
] |
||||
|
|
||||
|
ROOT_URLCONF = 'divemanager.urls' |
||||
|
|
||||
|
TEMPLATES = [ |
||||
|
{ |
||||
|
'BACKEND': 'django.template.backends.django.DjangoTemplates', |
||||
|
'DIRS': [BASE_DIR / 'templates'], |
||||
|
'APP_DIRS': True, |
||||
|
'OPTIONS': {'context_processors': [ |
||||
|
'django.template.context_processors.debug', |
||||
|
'django.template.context_processors.request', |
||||
|
'django.contrib.auth.context_processors.auth', |
||||
|
'django.contrib.messages.context_processors.messages', |
||||
|
]}, |
||||
|
}, |
||||
|
] |
||||
|
|
||||
|
DATABASES = { |
||||
|
'default': { |
||||
|
'ENGINE': 'django.db.backends.sqlite3', |
||||
|
'NAME': BASE_DIR / 'db.sqlite3', |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
STATIC_URL = '/static/' |
||||
|
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField' |
||||
@ -0,0 +1,7 @@ |
|||||
|
|
||||
|
from django.contrib import admin |
||||
|
from django.urls import path |
||||
|
|
||||
|
urlpatterns = [ |
||||
|
path('admin/', admin.site.urls), |
||||
|
] |
||||
@ -0,0 +1,7 @@ |
|||||
|
from django.contrib import admin |
||||
|
from .models import Event |
||||
|
|
||||
|
@admin.register(Event) |
||||
|
class EventAdmin(admin.ModelAdmin): |
||||
|
list_display = ("title", "start_datetime", "dive_base", "is_deleted") |
||||
|
list_filter = ("dive_base", "is_deleted") |
||||
@ -0,0 +1,23 @@ |
|||||
|
# Generated by Django 5.2.9 on 2026-01-06 11:46 |
||||
|
|
||||
|
from django.db import migrations, models |
||||
|
|
||||
|
|
||||
|
class Migration(migrations.Migration): |
||||
|
|
||||
|
initial = True |
||||
|
|
||||
|
dependencies = [ |
||||
|
] |
||||
|
|
||||
|
operations = [ |
||||
|
migrations.CreateModel( |
||||
|
name='Event', |
||||
|
fields=[ |
||||
|
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), |
||||
|
('title', models.CharField(max_length=255)), |
||||
|
('start_datetime', models.DateTimeField()), |
||||
|
('is_deleted', models.BooleanField(default=False)), |
||||
|
], |
||||
|
), |
||||
|
] |
||||
@ -0,0 +1,29 @@ |
|||||
|
# Generated by Django 5.2.9 on 2026-01-06 11:46 |
||||
|
|
||||
|
import django.db.models.deletion |
||||
|
from django.conf import settings |
||||
|
from django.db import migrations, models |
||||
|
|
||||
|
|
||||
|
class Migration(migrations.Migration): |
||||
|
|
||||
|
initial = True |
||||
|
|
||||
|
dependencies = [ |
||||
|
('divebases', '0001_initial'), |
||||
|
('events', '0001_initial'), |
||||
|
migrations.swappable_dependency(settings.AUTH_USER_MODEL), |
||||
|
] |
||||
|
|
||||
|
operations = [ |
||||
|
migrations.AddField( |
||||
|
model_name='event', |
||||
|
name='created_by', |
||||
|
field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='created_events', to=settings.AUTH_USER_MODEL), |
||||
|
), |
||||
|
migrations.AddField( |
||||
|
model_name='event', |
||||
|
name='dive_base', |
||||
|
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='events', to='divebases.divebase'), |
||||
|
), |
||||
|
] |
||||
@ -0,0 +1,26 @@ |
|||||
|
from django.db import models |
||||
|
from django.conf import settings |
||||
|
|
||||
|
User = settings.AUTH_USER_MODEL |
||||
|
|
||||
|
|
||||
|
class Event(models.Model): |
||||
|
title = models.CharField(max_length=255) |
||||
|
start_datetime = models.DateTimeField() |
||||
|
|
||||
|
dive_base = models.ForeignKey( |
||||
|
'divebases.DiveBase', |
||||
|
on_delete=models.CASCADE, |
||||
|
related_name='events' |
||||
|
) |
||||
|
|
||||
|
created_by = models.ForeignKey( |
||||
|
User, |
||||
|
on_delete=models.PROTECT, |
||||
|
related_name='created_events' |
||||
|
) |
||||
|
|
||||
|
is_deleted = models.BooleanField(default=False) |
||||
|
|
||||
|
def __str__(self): |
||||
|
return self.title |
||||
@ -0,0 +1,8 @@ |
|||||
|
from django.contrib import admin |
||||
|
from .models import InfoArticle |
||||
|
|
||||
|
|
||||
|
@admin.register(InfoArticle) |
||||
|
class InfoArticleAdmin(admin.ModelAdmin): |
||||
|
list_display = ("title", "dive_base", "created_at", "is_deleted") |
||||
|
list_filter = ("dive_base", "is_deleted") |
||||
@ -0,0 +1,24 @@ |
|||||
|
# Generated by Django 5.2.9 on 2026-01-06 11:46 |
||||
|
|
||||
|
from django.db import migrations, models |
||||
|
|
||||
|
|
||||
|
class Migration(migrations.Migration): |
||||
|
|
||||
|
initial = True |
||||
|
|
||||
|
dependencies = [ |
||||
|
] |
||||
|
|
||||
|
operations = [ |
||||
|
migrations.CreateModel( |
||||
|
name='InfoArticle', |
||||
|
fields=[ |
||||
|
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), |
||||
|
('title', models.CharField(max_length=255)), |
||||
|
('content', models.TextField()), |
||||
|
('created_at', models.DateTimeField(auto_now_add=True)), |
||||
|
('is_deleted', models.BooleanField(default=False)), |
||||
|
], |
||||
|
), |
||||
|
] |
||||
@ -0,0 +1,29 @@ |
|||||
|
# Generated by Django 5.2.9 on 2026-01-06 11:46 |
||||
|
|
||||
|
import django.db.models.deletion |
||||
|
from django.conf import settings |
||||
|
from django.db import migrations, models |
||||
|
|
||||
|
|
||||
|
class Migration(migrations.Migration): |
||||
|
|
||||
|
initial = True |
||||
|
|
||||
|
dependencies = [ |
||||
|
('divebases', '0001_initial'), |
||||
|
('infos', '0001_initial'), |
||||
|
migrations.swappable_dependency(settings.AUTH_USER_MODEL), |
||||
|
] |
||||
|
|
||||
|
operations = [ |
||||
|
migrations.AddField( |
||||
|
model_name='infoarticle', |
||||
|
name='created_by', |
||||
|
field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='articles', to=settings.AUTH_USER_MODEL), |
||||
|
), |
||||
|
migrations.AddField( |
||||
|
model_name='infoarticle', |
||||
|
name='dive_base', |
||||
|
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='articles', to='divebases.divebase'), |
||||
|
), |
||||
|
] |
||||
@ -0,0 +1,28 @@ |
|||||
|
from django.db import models |
||||
|
from django.conf import settings |
||||
|
|
||||
|
User = settings.AUTH_USER_MODEL |
||||
|
|
||||
|
|
||||
|
class InfoArticle(models.Model): |
||||
|
title = models.CharField(max_length=255) |
||||
|
content = models.TextField() |
||||
|
|
||||
|
dive_base = models.ForeignKey( |
||||
|
'divebases.DiveBase', |
||||
|
on_delete=models.CASCADE, |
||||
|
related_name='articles' |
||||
|
) |
||||
|
|
||||
|
created_by = models.ForeignKey( |
||||
|
User, |
||||
|
on_delete=models.PROTECT, |
||||
|
related_name='articles' |
||||
|
) |
||||
|
|
||||
|
created_at = models.DateTimeField(auto_now_add=True) |
||||
|
|
||||
|
is_deleted = models.BooleanField(default=False) |
||||
|
|
||||
|
def __str__(self): |
||||
|
return self.title |
||||
@ -0,0 +1,9 @@ |
|||||
|
|
||||
|
#!/usr/bin/env python |
||||
|
import os, sys |
||||
|
def main(): |
||||
|
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'divemanager.settings') |
||||
|
from django.core.management import execute_from_command_line |
||||
|
execute_from_command_line(sys.argv) |
||||
|
if __name__ == '__main__': |
||||
|
main() |
||||
@ -0,0 +1 @@ |
|||||
|
default_app_config = "users.apps.UsersConfig" |
||||
@ -0,0 +1,8 @@ |
|||||
|
from django.contrib import admin |
||||
|
from .models import User |
||||
|
|
||||
|
@admin.register(User) |
||||
|
class UserAdmin(admin.ModelAdmin): |
||||
|
list_display = ("username", "email", "role", "dive_base", "is_staff") |
||||
|
list_filter = ("role", "dive_base") |
||||
|
search_fields = ("username", "email") |
||||
@ -0,0 +1,5 @@ |
|||||
|
from django.apps import AppConfig |
||||
|
|
||||
|
class UsersConfig(AppConfig): |
||||
|
default_auto_field = "django.db.models.BigAutoField" |
||||
|
name = "users" |
||||
@ -0,0 +1,49 @@ |
|||||
|
# Generated by Django 5.2.9 on 2026-01-06 11:46 |
||||
|
|
||||
|
import django.contrib.auth.models |
||||
|
import django.contrib.auth.validators |
||||
|
import django.db.models.deletion |
||||
|
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'), |
||||
|
('divebases', '0001_initial'), |
||||
|
] |
||||
|
|
||||
|
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')), |
||||
|
('role', models.CharField(choices=[('USER', 'User'), ('ADMIN', 'Admin')], default='USER', max_length=10)), |
||||
|
('dive_certificate', models.CharField(blank=True, max_length=255)), |
||||
|
('dive_base', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='divebases.divebase')), |
||||
|
('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()), |
||||
|
], |
||||
|
), |
||||
|
] |
||||
@ -0,0 +1,9 @@ |
|||||
|
|
||||
|
from django.contrib.auth.models import AbstractUser |
||||
|
from django.db import models |
||||
|
|
||||
|
class User(AbstractUser): |
||||
|
ROLE_CHOICES = [('USER','User'), ('ADMIN','Admin')] |
||||
|
role = models.CharField(max_length=10, choices=ROLE_CHOICES, default='USER') |
||||
|
dive_certificate = models.CharField(max_length=255, blank=True) |
||||
|
dive_base = models.ForeignKey('divebases.DiveBase', null=True, blank=True, on_delete=models.SET_NULL) |
||||
Loading…
Reference in new issue