Compare commits
16 Commits
85a63f6c30
...
a47ffa0b0b
| Author | SHA1 | Date | |
|---|---|---|---|
| a47ffa0b0b | |||
| 39ceb520ba | |||
| 8e34e1056a | |||
| e73d020155 | |||
| b3c2bad3c2 | |||
| 51ba0fb693 | |||
| 837884bb02 | |||
| f6887d07df | |||
| 7015a79e07 | |||
| e28ceb2da1 | |||
| a1c9a6a3cc | |||
| 3af6652e68 | |||
| 50324f190b | |||
| 4fda1dd1df | |||
| cf433c60f6 | |||
| a6ff6e1eca |
138
.gitignore
vendored
Normal file
138
.gitignore
vendored
Normal file
@ -0,0 +1,138 @@
|
|||||||
|
# Django #
|
||||||
|
*.log
|
||||||
|
*.pot
|
||||||
|
*.pyc
|
||||||
|
__pycache__
|
||||||
|
db.sqlite3
|
||||||
|
media
|
||||||
|
|
||||||
|
# Backup files #
|
||||||
|
*.bak
|
||||||
|
|
||||||
|
# If you are using PyCharm #
|
||||||
|
# User-specific stuff
|
||||||
|
.idea/**/workspace.xml
|
||||||
|
.idea/**/tasks.xml
|
||||||
|
.idea/**/usage.statistics.xml
|
||||||
|
.idea/**/dictionaries
|
||||||
|
.idea/**/shelf
|
||||||
|
|
||||||
|
# AWS User-specific
|
||||||
|
.idea/**/aws.xml
|
||||||
|
|
||||||
|
# Generated files
|
||||||
|
.idea/**/contentModel.xml
|
||||||
|
|
||||||
|
# Sensitive or high-churn files
|
||||||
|
.idea/**/dataSources/
|
||||||
|
.idea/**/dataSources.ids
|
||||||
|
.idea/**/dataSources.local.xml
|
||||||
|
.idea/**/sqlDataSources.xml
|
||||||
|
.idea/**/dynamic.xml
|
||||||
|
.idea/**/uiDesigner.xml
|
||||||
|
.idea/**/dbnavigator.xml
|
||||||
|
|
||||||
|
# Gradle
|
||||||
|
.idea/**/gradle.xml
|
||||||
|
.idea/**/libraries
|
||||||
|
|
||||||
|
# File-based project format
|
||||||
|
*.iws
|
||||||
|
|
||||||
|
# IntelliJ
|
||||||
|
out/
|
||||||
|
|
||||||
|
# JIRA plugin
|
||||||
|
atlassian-ide-plugin.xml
|
||||||
|
|
||||||
|
# Python #
|
||||||
|
*.py[cod]
|
||||||
|
*$py.class
|
||||||
|
|
||||||
|
# Distribution / packaging
|
||||||
|
.Python build/
|
||||||
|
develop-eggs/
|
||||||
|
dist/
|
||||||
|
downloads/
|
||||||
|
eggs/
|
||||||
|
.eggs/
|
||||||
|
lib/
|
||||||
|
lib64/
|
||||||
|
parts/
|
||||||
|
sdist/
|
||||||
|
var/
|
||||||
|
wheels/
|
||||||
|
*.whl
|
||||||
|
*.egg-info/
|
||||||
|
.installed.cfg
|
||||||
|
*.egg
|
||||||
|
*.manifest
|
||||||
|
*.spec
|
||||||
|
|
||||||
|
# Installer logs
|
||||||
|
pip-log.txt
|
||||||
|
pip-delete-this-directory.txt
|
||||||
|
|
||||||
|
# Unit test / coverage reports
|
||||||
|
htmlcov/
|
||||||
|
.tox/
|
||||||
|
.coverage
|
||||||
|
.coverage.*
|
||||||
|
.cache
|
||||||
|
.pytest_cache/
|
||||||
|
nosetests.xml
|
||||||
|
coverage.xml
|
||||||
|
*.cover
|
||||||
|
.hypothesis/
|
||||||
|
|
||||||
|
# Jupyter Notebook
|
||||||
|
.ipynb_checkpoints
|
||||||
|
|
||||||
|
# pyenv
|
||||||
|
.python-version
|
||||||
|
|
||||||
|
# celery
|
||||||
|
celerybeat-schedule.*
|
||||||
|
|
||||||
|
# SageMath parsed files
|
||||||
|
*.sage.py
|
||||||
|
|
||||||
|
# Environments
|
||||||
|
.env
|
||||||
|
.venv
|
||||||
|
env/
|
||||||
|
venv/
|
||||||
|
ENV/
|
||||||
|
env.bak/
|
||||||
|
venv.bak/
|
||||||
|
|
||||||
|
# mkdocs documentation
|
||||||
|
/site
|
||||||
|
|
||||||
|
# mypy
|
||||||
|
.mypy_cache/
|
||||||
|
|
||||||
|
# Sublime Text #
|
||||||
|
*.tmlanguage.cache
|
||||||
|
*.tmPreferences.cache
|
||||||
|
*.stTheme.cache
|
||||||
|
*.sublime-workspace
|
||||||
|
*.sublime-project
|
||||||
|
|
||||||
|
# sftp configuration file
|
||||||
|
sftp-config.json
|
||||||
|
|
||||||
|
# Package control specific files Package
|
||||||
|
Control.last-run
|
||||||
|
Control.ca-list
|
||||||
|
Control.ca-bundle
|
||||||
|
Control.system-ca-bundle
|
||||||
|
GitHub.sublime-settings
|
||||||
|
|
||||||
|
# Visual Studio Code #
|
||||||
|
.vscode/*
|
||||||
|
!.vscode/settings.json
|
||||||
|
!.vscode/tasks.json
|
||||||
|
!.vscode/launch.json
|
||||||
|
!.vscode/extensions.json
|
||||||
|
.history
|
||||||
@ -9,8 +9,10 @@ https://docs.djangoproject.com/en/5.2/topics/settings/
|
|||||||
For the full list of settings and their values, see
|
For the full list of settings and their values, see
|
||||||
https://docs.djangoproject.com/en/5.2/ref/settings/
|
https://docs.djangoproject.com/en/5.2/ref/settings/
|
||||||
"""
|
"""
|
||||||
|
import pymysql
|
||||||
|
pymysql.install_as_MySQLdb()
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
from decouple import config
|
||||||
|
|
||||||
# Build paths inside the project like this: BASE_DIR / 'subdir'.
|
# Build paths inside the project like this: BASE_DIR / 'subdir'.
|
||||||
BASE_DIR = Path(__file__).resolve().parent.parent
|
BASE_DIR = Path(__file__).resolve().parent.parent
|
||||||
@ -25,7 +27,7 @@ SECRET_KEY = 'django-insecure-tulz*odc=l1x(g^-=ne!y7^@lg1uce)=ha^!0wi5qkifq&#^sg
|
|||||||
# SECURITY WARNING: don't run with debug turned on in production!
|
# SECURITY WARNING: don't run with debug turned on in production!
|
||||||
DEBUG = True
|
DEBUG = True
|
||||||
|
|
||||||
ALLOWED_HOSTS = []
|
ALLOWED_HOSTS = [ "albani.sternbauer.de" ]
|
||||||
|
|
||||||
|
|
||||||
# Application definition
|
# Application definition
|
||||||
@ -37,6 +39,7 @@ INSTALLED_APPS = [
|
|||||||
'django.contrib.sessions',
|
'django.contrib.sessions',
|
||||||
'django.contrib.messages',
|
'django.contrib.messages',
|
||||||
'django.contrib.staticfiles',
|
'django.contrib.staticfiles',
|
||||||
|
'member',
|
||||||
]
|
]
|
||||||
|
|
||||||
MIDDLEWARE = [
|
MIDDLEWARE = [
|
||||||
@ -74,8 +77,12 @@ WSGI_APPLICATION = 'FloriCore.wsgi.application'
|
|||||||
|
|
||||||
DATABASES = {
|
DATABASES = {
|
||||||
'default': {
|
'default': {
|
||||||
'ENGINE': 'django.db.backends.sqlite3',
|
'ENGINE': 'django.db.backends.mysql',
|
||||||
'NAME': BASE_DIR / 'db.sqlite3',
|
'NAME': config('DB_NAME'),
|
||||||
|
'USER': config('DB_USER'),
|
||||||
|
'PASSWORD': config('DB_PASSWORD'),
|
||||||
|
'HOST': config('DB_HOST', default='localhost'),
|
||||||
|
'PORT': config('DB_PORT', default='3306'),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -15,8 +15,9 @@ Including another URLconf
|
|||||||
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
|
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
|
||||||
"""
|
"""
|
||||||
from django.contrib import admin
|
from django.contrib import admin
|
||||||
from django.urls import path
|
from django.urls import path,include
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
|
path('', include('member.urls')),
|
||||||
path('admin/', admin.site.urls),
|
path('admin/', admin.site.urls),
|
||||||
]
|
]
|
||||||
|
|||||||
0
member/__init__.py
Normal file
0
member/__init__.py
Normal file
3
member/admin.py
Normal file
3
member/admin.py
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
from django.contrib import admin
|
||||||
|
|
||||||
|
# Register your models here.
|
||||||
6
member/apps.py
Normal file
6
member/apps.py
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
from django.apps import AppConfig
|
||||||
|
|
||||||
|
|
||||||
|
class MemberConfig(AppConfig):
|
||||||
|
default_auto_field = 'django.db.models.BigAutoField'
|
||||||
|
name = 'member'
|
||||||
0
member/management/__init__.py
Normal file
0
member/management/__init__.py
Normal file
0
member/management/commands/__init__.py
Normal file
0
member/management/commands/__init__.py
Normal file
49
member/management/commands/seed.py
Normal file
49
member/management/commands/seed.py
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
from django.conf import settings
|
||||||
|
from django.core.management.base import BaseCommand
|
||||||
|
from member.models import Person, UserAccount
|
||||||
|
from django.contrib.auth.hashers import make_password
|
||||||
|
|
||||||
|
class Command(BaseCommand):
|
||||||
|
help = "Füllt die DB mit Beispieldaten"
|
||||||
|
|
||||||
|
def handle(self, *args, **kwargs):
|
||||||
|
if not settings.DEBUG:
|
||||||
|
raise CommandError("❌ Dieses Kommando darf nur in DEBUG-Umgebungen verwendet werden.")
|
||||||
|
# Bestehende Daten löschen
|
||||||
|
self.stdout.write("🧹 Lösche bestehende Personen und Benutzerkonten...")
|
||||||
|
UserAccount.objects.all().delete()
|
||||||
|
Person.objects.all().delete()
|
||||||
|
|
||||||
|
# Personen anlegen
|
||||||
|
self.stdout.write("👤 Erstelle Personen...")
|
||||||
|
p0 = Person.objects.create(vorname="Florian", nachname="von Lorch", geburtsdatum="0304-05-04", aktiv=True)
|
||||||
|
p1 = Person.objects.create(vorname="Max", nachname="Mustermann", geburtsdatum="1980-05-01", aktiv=True)
|
||||||
|
p2 = Person.objects.create(vorname="Erika", nachname="Beispiel", geburtsdatum="1992-03-15", aktiv=True)
|
||||||
|
p3 = Person.objects.create(vorname="Thomas", nachname="Feuer", geburtsdatum=None, aktiv=True)
|
||||||
|
p4 = Person.objects.create(vorname="Julia", nachname="Wehr", geburtsdatum="1999-11-20", aktiv=False)
|
||||||
|
|
||||||
|
# Benutzerkonten anlegen
|
||||||
|
self.stdout.write("🔐 Erstelle Benutzerkonten...")
|
||||||
|
UserAccount.objects.create(
|
||||||
|
person=p0,
|
||||||
|
userName="admin",
|
||||||
|
passwort_hash=make_password("adminpass1234"),
|
||||||
|
role="superadmin",
|
||||||
|
isActive=True,
|
||||||
|
)
|
||||||
|
UserAccount.objects.create(
|
||||||
|
person=p1,
|
||||||
|
userName="maxadmin",
|
||||||
|
passwort_hash=make_password("adminpass123"),
|
||||||
|
role="admin",
|
||||||
|
isActive=True,
|
||||||
|
)
|
||||||
|
UserAccount.objects.create(
|
||||||
|
person=p2,
|
||||||
|
userName="erikam",
|
||||||
|
passwort_hash=make_password("mitglied456"),
|
||||||
|
role="mitglied",
|
||||||
|
isActive=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
self.stdout.write(self.style.SUCCESS("✅ Testdaten erfolgreich eingespielt."))
|
||||||
37
member/migrations/0001_initial.py
Normal file
37
member/migrations/0001_initial.py
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
# Generated by Django 5.2.1 on 2025-05-10 12:49
|
||||||
|
|
||||||
|
import django.db.models.deletion
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
initial = True
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='Person',
|
||||||
|
fields=[
|
||||||
|
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('vorname', models.CharField(max_length=100)),
|
||||||
|
('nachname', models.CharField(max_length=100)),
|
||||||
|
('geburtsdatum', models.DateField(blank=True, null=True)),
|
||||||
|
('aktiv', models.BooleanField(default=True)),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='UserAccount',
|
||||||
|
fields=[
|
||||||
|
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('userName', models.CharField(max_length=150, unique=True)),
|
||||||
|
('passwort_hash', models.CharField(max_length=128)),
|
||||||
|
('role', models.CharField(choices=[('mitglied', 'Mitglied'), ('geraetewart', 'Gerätewart'), ('kommandant', 'Kommandant'), ('admin', 'Administrator')], max_length=50)),
|
||||||
|
('isActive', models.BooleanField(default=True)),
|
||||||
|
('lastLogin', models.DateTimeField(blank=True, null=True)),
|
||||||
|
('person', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='benutzerkonten', to='member.person')),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
]
|
||||||
0
member/migrations/__init__.py
Normal file
0
member/migrations/__init__.py
Normal file
11
member/models/Person.py
Normal file
11
member/models/Person.py
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
from django.db import models
|
||||||
|
from django.utils import timezone
|
||||||
|
|
||||||
|
class Person(models.Model):
|
||||||
|
vorname = models.CharField(max_length=100)
|
||||||
|
nachname = models.CharField(max_length=100)
|
||||||
|
geburtsdatum = models.DateField(null=True, blank=True)
|
||||||
|
aktiv = models.BooleanField(default=True)
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return f"{self.vorname} {self.nachname}"
|
||||||
20
member/models/UserAccount.py
Normal file
20
member/models/UserAccount.py
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
from django.db import models
|
||||||
|
from django.utils import timezone
|
||||||
|
from .Person import Person
|
||||||
|
|
||||||
|
|
||||||
|
class UserAccount(models.Model):
|
||||||
|
person = models.ForeignKey(Person, on_delete=models.CASCADE, related_name='benutzerkonten')
|
||||||
|
userName = models.CharField(max_length=150, unique=True)
|
||||||
|
passwort_hash = models.CharField(max_length=128)
|
||||||
|
role = models.CharField(max_length=50, choices=[
|
||||||
|
('mitglied', 'Mitglied'),
|
||||||
|
('geraetewart', 'Gerätewart'),
|
||||||
|
('kommandant', 'Kommandant'),
|
||||||
|
('admin', 'Administrator'),
|
||||||
|
])
|
||||||
|
isActive = models.BooleanField(default=True)
|
||||||
|
lastLogin = models.DateTimeField(null=True, blank=True)
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return f"{self.benutzername} ({self.rolle})"
|
||||||
2
member/models/__init__.py
Normal file
2
member/models/__init__.py
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
from .Person import Person
|
||||||
|
from .UserAccount import UserAccount
|
||||||
131
member/static/member/css/styles.css
Normal file
131
member/static/member/css/styles.css
Normal file
@ -0,0 +1,131 @@
|
|||||||
|
:root {
|
||||||
|
--bg-dark: #121212;
|
||||||
|
--bg-sidebar: #2a0000;
|
||||||
|
--bg-panel: #1e1e1e;
|
||||||
|
--bg-accent: #b22222;
|
||||||
|
--text-light: #f1f1f1;
|
||||||
|
--text-muted: #999;
|
||||||
|
--highlight: #f5a623;
|
||||||
|
--font-sans: 'Inter', 'Roboto', sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
margin: 0;
|
||||||
|
font-family: var(--font-sans);
|
||||||
|
background-color: var(--bg-dark);
|
||||||
|
color: var(--text-light);
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar {
|
||||||
|
width: 220px;
|
||||||
|
height: 100vh;
|
||||||
|
background-color: var(--bg-sidebar);
|
||||||
|
color: var(--text-light);
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar h2 {
|
||||||
|
font-size: 1.2rem;
|
||||||
|
margin-bottom: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar nav a {
|
||||||
|
color: var(--text-light);
|
||||||
|
text-decoration: none;
|
||||||
|
margin: 10px 0;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
padding: 8px 12px;
|
||||||
|
border-radius: 4px;
|
||||||
|
transition: background 0.2s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar nav a:hover,
|
||||||
|
.sidebar nav a.active {
|
||||||
|
background-color: var(--bg-accent);
|
||||||
|
}
|
||||||
|
|
||||||
|
.main {
|
||||||
|
padding: 20px;
|
||||||
|
display: flex;
|
||||||
|
height: 100vh;
|
||||||
|
box-sizing: border-box;
|
||||||
|
background-color: var(--bg-dark);
|
||||||
|
overflow-y: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.members-table {
|
||||||
|
flex: 2;
|
||||||
|
margin-right: 20px;
|
||||||
|
background-color: var(--bg-panel);
|
||||||
|
padding: 20px;
|
||||||
|
border-radius: 8px;
|
||||||
|
overflow-y: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.members-table table {
|
||||||
|
width: 100%;
|
||||||
|
border-collapse: collapse;
|
||||||
|
}
|
||||||
|
|
||||||
|
.members-table th,
|
||||||
|
.members-table td {
|
||||||
|
text-align: left;
|
||||||
|
padding: 10px;
|
||||||
|
border-bottom: 1px solid #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
.members-table th {
|
||||||
|
color: var(--highlight);
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.members-table tr:hover {
|
||||||
|
background-color: rgba(255, 255, 255, 0.05);
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.details-panel {
|
||||||
|
flex: 1;
|
||||||
|
background-color: var(--bg-panel);
|
||||||
|
padding: 20px;
|
||||||
|
border-radius: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.details-panel h3 {
|
||||||
|
margin-top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.details-panel .info {
|
||||||
|
margin-bottom: 10px;
|
||||||
|
color: var(--text-muted);
|
||||||
|
}
|
||||||
|
|
||||||
|
.badge {
|
||||||
|
display: inline-block;
|
||||||
|
background-color: var(--bg-accent);
|
||||||
|
padding: 4px 8px;
|
||||||
|
border-radius: 4px;
|
||||||
|
font-size: 0.8rem;
|
||||||
|
color: #fff;
|
||||||
|
margin-right: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button {
|
||||||
|
background-color: var(--bg-accent);
|
||||||
|
color: #fff;
|
||||||
|
border: none;
|
||||||
|
padding: 8px 16px;
|
||||||
|
font-size: 0.9rem;
|
||||||
|
border-radius: 4px;
|
||||||
|
cursor: pointer;
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button:hover {
|
||||||
|
background-color: #d63031;
|
||||||
|
}
|
||||||
|
|
||||||
13
member/templates/details.html
Normal file
13
member/templates/details.html
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
{% extends "master.html" %}
|
||||||
|
|
||||||
|
{% block title %}
|
||||||
|
Details zu {{ mymember.firstname }} {{ mymember.lastname }}
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<h1>{{ mymember.vorname }} {{ mymember.nachname }}</h1>
|
||||||
|
|
||||||
|
<p>Geburtsdatum: {{ mymember.geburtsdatum }}</p>
|
||||||
|
|
||||||
|
<p>Back to <a href="/members">Members</a></p>
|
||||||
|
{% endblock %}
|
||||||
14
member/templates/master.html
Normal file
14
member/templates/master.html
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
{% load static %}
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>{% block title %}{% endblock %}</title>
|
||||||
|
<link rel="stylesheet" href="{% static 'member/css/styles.css' %}">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
{% include "partials/sidebar.html" %}
|
||||||
|
<div class="main">
|
||||||
|
{% block content %}{% endblock %}
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
19
member/templates/memberlist.html
Normal file
19
member/templates/memberlist.html
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
{% extends "master.html" %}
|
||||||
|
|
||||||
|
{% block title %}
|
||||||
|
List of all persons
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<div class="members-table">
|
||||||
|
<h3>Members</h3>
|
||||||
|
<ul>
|
||||||
|
{% for x in mymembers %}
|
||||||
|
<li><a href="details/{{x.id}}"> {{ x.vorname }} {{ x.nachname }}</a></li>
|
||||||
|
{% empty %}
|
||||||
|
<li>Keine Datensaetze gefunden</li>
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{% endblock %}
|
||||||
7
member/templates/partials/sidebar.html
Normal file
7
member/templates/partials/sidebar.html
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
<div class="sidebar">
|
||||||
|
<h2>🧯 VERWALTUNG</h2>
|
||||||
|
|
||||||
|
<nav>
|
||||||
|
<a href={% url 'members' %} class="{% if request.path == '/members/' %}active{% endif %}">Mitglieder</a>
|
||||||
|
</nav>
|
||||||
|
</div>
|
||||||
3
member/tests.py
Normal file
3
member/tests.py
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
from django.test import TestCase
|
||||||
|
|
||||||
|
# Create your tests here.
|
||||||
7
member/urls.py
Normal file
7
member/urls.py
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
from django.urls import path
|
||||||
|
from . import views
|
||||||
|
|
||||||
|
urlpatterns = [
|
||||||
|
path('members/', views.members, name='members'),
|
||||||
|
path('members/details/<int:id>', views.details, name="details"),
|
||||||
|
]
|
||||||
19
member/views.py
Normal file
19
member/views.py
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
from django.http import HttpResponse
|
||||||
|
from django.template import loader
|
||||||
|
from .models import Person
|
||||||
|
|
||||||
|
def members(request):
|
||||||
|
mymembers=Person.objects.all().values()
|
||||||
|
template=loader.get_template("memberlist.html")
|
||||||
|
context = {
|
||||||
|
'mymembers': mymembers
|
||||||
|
}
|
||||||
|
return HttpResponse(template.render(context, request))
|
||||||
|
|
||||||
|
def details(request, id):
|
||||||
|
mymember = Person.objects.get(id=id)
|
||||||
|
template = loader.get_template("details.html")
|
||||||
|
context = {
|
||||||
|
'mymember': mymember
|
||||||
|
}
|
||||||
|
return HttpResponse(template.render(context, request))
|
||||||
6
requirements.txt
Normal file
6
requirements.txt
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
asgiref==3.8.1
|
||||||
|
Django==5.2.1
|
||||||
|
mysql-connector-python==9.3.0
|
||||||
|
PyMySQL==1.1.1
|
||||||
|
python-decouple==3.8
|
||||||
|
sqlparse==0.5.3
|
||||||
Loading…
x
Reference in New Issue
Block a user