Compare commits
6 Commits
982ba5a676
...
80577d89de
| Author | SHA1 | Date | |
|---|---|---|---|
| 80577d89de | |||
| b4305aa7fa | |||
| f05116e01b | |||
| 1e720228be | |||
| 69941166a1 | |||
| 15750517f2 |
1
.gitignore
vendored
1
.gitignore
vendored
@ -136,3 +136,4 @@ GitHub.sublime-settings
|
|||||||
!.vscode/launch.json
|
!.vscode/launch.json
|
||||||
!.vscode/extensions.json
|
!.vscode/extensions.json
|
||||||
.history
|
.history
|
||||||
|
.vs/*
|
||||||
@ -12,7 +12,8 @@ https://docs.djangoproject.com/en/5.2/ref/settings/
|
|||||||
import pymysql
|
import pymysql
|
||||||
pymysql.install_as_MySQLdb()
|
pymysql.install_as_MySQLdb()
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from decouple import config
|
from decouple import config, Csv
|
||||||
|
|
||||||
|
|
||||||
# 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
|
||||||
@ -27,7 +28,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 = [ "albani.sternbauer.de" ]
|
ALLOWED_HOSTS = config("DJANGO_ALLOWED_HOSTS", default="localhost", cast=Csv())
|
||||||
|
|
||||||
|
|
||||||
# Application definition
|
# Application definition
|
||||||
@ -125,6 +126,10 @@ USE_TZ = True
|
|||||||
|
|
||||||
STATIC_URL = 'static/'
|
STATIC_URL = 'static/'
|
||||||
|
|
||||||
|
STATICFILES_DIRS = [
|
||||||
|
BASEDIR / "static"
|
||||||
|
]
|
||||||
|
|
||||||
# Default primary key field type
|
# Default primary key field type
|
||||||
# https://docs.djangoproject.com/en/5.2/ref/settings/#default-auto-field
|
# https://docs.djangoproject.com/en/5.2/ref/settings/#default-auto-field
|
||||||
|
|
||||||
|
|||||||
@ -13,12 +13,19 @@ class PersonForm(forms.ModelForm):
|
|||||||
|
|
||||||
|
|
||||||
class AccountForm(forms.ModelForm):
|
class AccountForm(forms.ModelForm):
|
||||||
password=forms.CharField(widget=forms.PasswordInput())
|
password=forms.CharField(widget=forms.PasswordInput(), required=False)
|
||||||
confirm_password=forms.CharField(widget=forms.PasswordInput())
|
confirm_password=forms.CharField(widget=forms.PasswordInput(), required=False)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = UserAccount
|
model = UserAccount
|
||||||
fields = ['username', 'password']
|
fields = ['username', 'password', 'role']
|
||||||
|
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
super().__init__(*args, **kwargs)
|
||||||
|
|
||||||
|
if self.instance.pk is None:
|
||||||
|
self.fields['password'].required=True
|
||||||
|
self.fields['confirm_password'].required=True
|
||||||
|
|
||||||
def clean(self):
|
def clean(self):
|
||||||
cleaned_data = super(AccountForm, self).clean()
|
cleaned_data = super(AccountForm, self).clean()
|
||||||
@ -27,4 +34,14 @@ class AccountForm(forms.ModelForm):
|
|||||||
|
|
||||||
if passwordStr != confirm_passwordStr:
|
if passwordStr != confirm_passwordStr:
|
||||||
raise forms.ValidateError("password and confirm_password does not match")
|
raise forms.ValidateError("password and confirm_password does not match")
|
||||||
|
|
||||||
|
def save(self, commit=True):
|
||||||
|
user = super().save(commit=False)
|
||||||
|
pw = self.cleaned_data.get("password")
|
||||||
|
if pw:
|
||||||
|
user.set_password(pw)
|
||||||
|
if commit:
|
||||||
|
user.save()
|
||||||
|
return user
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
18
member/migrations/0003_alter_useraccount_role.py
Normal file
18
member/migrations/0003_alter_useraccount_role.py
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
# Generated by Django 5.2.1 on 2025-07-18 15:12
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('member', '0002_alter_useraccount_options_alter_useraccount_managers_and_more'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='useraccount',
|
||||||
|
name='role',
|
||||||
|
field=models.CharField(choices=[('mitglied', 'Mitglied'), ('geraetewart', 'Gerätewart'), ('kommandant', 'Kommandant'), ('admin', 'Administrator'), ('superadmin', 'Superadministrator')], default='mitglied', max_length=50),
|
||||||
|
),
|
||||||
|
]
|
||||||
@ -11,7 +11,9 @@ class UserAccount(AbstractUser):
|
|||||||
('geraetewart', 'Gerätewart'),
|
('geraetewart', 'Gerätewart'),
|
||||||
('kommandant', 'Kommandant'),
|
('kommandant', 'Kommandant'),
|
||||||
('admin', 'Administrator'),
|
('admin', 'Administrator'),
|
||||||
])
|
('superadmin', 'Superadministrator'),
|
||||||
|
], default='mitglied')
|
||||||
|
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return f"{self.benutzername} ({self.rolle})"
|
return f"{self.benutzername} ({self.rolle})"
|
||||||
|
|||||||
@ -16,6 +16,10 @@
|
|||||||
<label for="{{form.password.id_for_label}}">Password (confirmation)</label>
|
<label for="{{form.password.id_for_label}}">Password (confirmation)</label>
|
||||||
{{form.confirm_password}}
|
{{form.confirm_password}}
|
||||||
</div>
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="{{form.role.id_for_label}}">Rolle</label>
|
||||||
|
{{form.role}}
|
||||||
|
</div>
|
||||||
<button class="button" type="submit">Speichern</button>
|
<button class="button" type="submit">Speichern</button>
|
||||||
<a href="{% url 'details' id %}" class="button" style="background:#444;">Abbrechen</a>
|
<a href="{% url 'details' id %}" class="button" style="background:#444;">Abbrechen</a>
|
||||||
</form>
|
</form>
|
||||||
|
|||||||
@ -1,43 +1,22 @@
|
|||||||
{% extends "master.html" %}
|
{% extends "master.html" %}
|
||||||
{% load static %}
|
{% load static %}
|
||||||
{% load svg %}
|
|
||||||
|
|
||||||
|
|
||||||
{% block title %}
|
{% block title %}
|
||||||
Details zu {{ mymember.firstname }} {{ mymember.lastname }}
|
Details zu {{ mymember.vorname }} {{ mymember.nachname }}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div class="member-table">
|
<div class="member-table">
|
||||||
<h1>{{ mymember.vorname }} {{ mymember.nachname }}</h1>
|
<h1>{{ mymember.vorname }} {{ mymember.nachname }}</h1>
|
||||||
|
|
||||||
<p>Geburtsdatum: {{ mymember.geburtsdatum }}</p>
|
<p>Geburtsdatum: {{ mymember.geburtsdatum }}</p>
|
||||||
|
|
||||||
<table>
|
<div class="mb-4">
|
||||||
<thead>
|
<h2 class="h5">Accounts</h2>
|
||||||
<tr>
|
{% include "partials/account_table.html" %}
|
||||||
<th>Name</th>
|
</div>
|
||||||
<th>Rolle</th>
|
|
||||||
<th>Aktiv</th>
|
|
||||||
<th>Aktionen</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
{% for x in accounts %}
|
|
||||||
<tr>
|
|
||||||
<td>{{ x.username }}</td>
|
|
||||||
<td>{{ x.rolle }}</td>
|
|
||||||
<td>{% if x.aktiv %}{% inline_svg 'icons/uxwing/check.svg' 'icon' %}{% endif %}</td>
|
|
||||||
<td><a href="{% url 'edit_account' x.id %}" title="Bearbeiten"><img src="{% static 'icons/heroicons/pencil.svg'%}" class="icon"></a> <a href="{% url 'delete_account' x.id %}" title="Löschen"><img src="{% static 'icons/heroicons/trash.svg'%}" class="icon"></a></td>
|
|
||||||
</tr>
|
|
||||||
{% endfor %}
|
|
||||||
<tr>
|
|
||||||
<td colspan="4">
|
|
||||||
<a href="{% url 'create_account' mymember.id %}" class="button"><img src="{% static 'icons/heroicons/plus.svg'%}" class="icon"> Konto hinzufügen</a>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
|
|
||||||
<p>Back to <a href="/members">Members</a></p>
|
<p>Back to <a href="/members">Members</a></p>
|
||||||
|
|||||||
@ -3,6 +3,7 @@
|
|||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<title>{% block title %}{% endblock %}</title>
|
<title>{% block title %}{% endblock %}</title>
|
||||||
|
<link rel="stylesheet" href="{% static 'css/bootstrap.min.css' %}">
|
||||||
<link rel="stylesheet" href="{% static 'member/css/styles.css' %}">
|
<link rel="stylesheet" href="{% static 'member/css/styles.css' %}">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|||||||
28
member/templates/partials/account_table.html
Normal file
28
member/templates/partials/account_table.html
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
{% load static %}
|
||||||
|
{% load svg %}
|
||||||
|
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Name</th>
|
||||||
|
<th>Rolle</th>
|
||||||
|
<th>Aktiv</th>
|
||||||
|
<th>Aktionen</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{% for x in accounts %}
|
||||||
|
<tr>
|
||||||
|
<td>{{ x.username }}</td>
|
||||||
|
<td>{{ x.rolle }}</td>
|
||||||
|
<td>{% if x.aktiv %}{% inline_svg 'icons/uxwing/check.svg' 'icon' %}{% endif %}</td>
|
||||||
|
<td><a href="{% url 'edit_account' x.id %}" title="Bearbeiten"><img src="{% static 'icons/heroicons/pencil.svg'%}" class="icon"></a> <a href="{% url 'delete_account' x.id %}" title="Löschen"><img src="{% static 'icons/heroicons/trash.svg'%}" class="icon"></a></td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
<tr>
|
||||||
|
<td colspan="4">
|
||||||
|
<a href="{% url 'create_account' mymember.id %}" class="button"><img src="{% static 'icons/heroicons/plus.svg'%}" class="icon"> Konto hinzufügen</a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
6
static/css/bootstrap.min.css
vendored
Normal file
6
static/css/bootstrap.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
7
static/js/bootstrap.bundle.min.js
vendored
Normal file
7
static/js/bootstrap.bundle.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
Loading…
x
Reference in New Issue
Block a user