Eingabefelder werden dynamisch aus dem Model/Form erzeugt.

master
Ulf Wagner 2 years ago
parent 355ea34e03
commit a26752044b
  1. 21
      UGSdjangoProject/.idea/dataSources.xml
  2. 123
      UGSdjangoProject/.idea/dbnavigator.xml
  3. 6
      UGSdjangoProject/.idea/sqldialects.xml
  4. 19
      UGSdjangoProject/UGSdjangoProject/settings.py
  5. 58
      UGSdjangoProject/ugssim/form.py
  6. 17
      UGSdjangoProject/ugssim/migrations/0001_initial.py
  7. 4
      UGSdjangoProject/ugssim/models.py
  8. 1
      UGSdjangoProject/ugssim/templates/planungsparameter/companydata.html
  9. 22
      UGSdjangoProject/ugssim/templates/planungsparameter/mandantendaten.html
  10. 64
      UGSdjangoProject/ugssim/templates/planungsparameter/planungsparameter.html
  11. 5
      UGSdjangoProject/ugssim/templates/planungsparameter/summary.html
  12. 5
      UGSdjangoProject/ugssim/templates/ugssim/ugssim.html
  13. 0
      UGSdjangoProject/ugssim/templatetags/__init__.py
  14. 28
      UGSdjangoProject/ugssim/templatetags/read_dictonary.py
  15. 71
      UGSdjangoProject/ugssim/views.py

@ -0,0 +1,21 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="DataSourceManagerImpl" format="xml" multifile-model="true">
<data-source source="LOCAL" name="Django default" uuid="204bda06-bee8-47b6-b9ad-2440fd487d22">
<driver-ref>sqlite.xerial</driver-ref>
<synchronize>true</synchronize>
<imported>true</imported>
<remarks>$PROJECT_DIR$/UGSdjangoProject/settings.py</remarks>
<jdbc-driver>org.sqlite.JDBC</jdbc-driver>
<jdbc-url>jdbc:sqlite:C:\Users\Ulf Wagner\PycharmProjects\UGSdjangoProject\db.sqlite3</jdbc-url>
<working-dir>$ProjectFileDir$</working-dir>
</data-source>
<data-source source="LOCAL" name="ugssim@localhost" uuid="151fe7b4-8b3e-40f4-aa7e-b0087d782bb2">
<driver-ref>mariadb</driver-ref>
<synchronize>true</synchronize>
<jdbc-driver>org.mariadb.jdbc.Driver</jdbc-driver>
<jdbc-url>jdbc:mariadb://localhost:3306/ugssim</jdbc-url>
<working-dir>$ProjectFileDir$</working-dir>
</data-source>
</component>
</project>

@ -1,16 +1,135 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="DBNavigator.Project.DataEditorManager">
<record-view-column-sorting-type value="BY_INDEX" />
<value-preview-text-wrapping value="true" />
<value-preview-pinned value="false" />
</component>
<component name="DBNavigator.Project.DatabaseBrowserManager">
<autoscroll-to-editor value="false" />
<autoscroll-from-editor value="true" />
<show-object-properties value="true" />
<loaded-nodes />
</component>
<component name="DBNavigator.Project.DatabaseConsoleManager">
<connection id="0f0466f7-0c21-4ba2-a1e8-70c7298d934b">
<console name="Connection" type="STANDARD" schema="" session="Main" />
</connection>
</component>
<component name="DBNavigator.Project.DatabaseEditorStateManager">
<last-used-providers />
</component>
<component name="DBNavigator.Project.DatabaseFileManager">
<open-files />
<open-files>
<object connection-id="0f0466f7-0c21-4ba2-a1e8-70c7298d934b" object-ref="consoles/Connection" />
</open-files>
</component>
<component name="DBNavigator.Project.DatabaseSessionManager">
<connection id="0f0466f7-0c21-4ba2-a1e8-70c7298d934b" />
</component>
<component name="DBNavigator.Project.ObjectQuickFilterManager">
<last-used-operator value="EQUAL" />
<filters />
</component>
<component name="DBNavigator.Project.Settings">
<connections />
<connections>
<connection id="0f0466f7-0c21-4ba2-a1e8-70c7298d934b" active="true" signed="true">
<database>
<name value="Connection" />
<description value="" />
<database-type value="SQLITE" />
<config-type value="BASIC" />
<database-version value="9999.0" />
<driver-source value="BUNDLED" />
<driver-library value="" />
<driver value="" />
<url-type value="FILE" />
<host value="" />
<port value="" />
<database value="" />
<tns-folder value="" />
<tns-profile value="" />
<files>
<file path="sqlite.db" schema="main" />
</files>
<type value="NONE" />
<user value="" />
<deprecated-pwd value="" />
</database>
<properties>
<auto-commit value="false" />
</properties>
<ssh-settings>
<active value="false" />
<proxy-host value="" />
<proxy-port value="22" />
<proxy-user value="" />
<deprecated-proxy-pwd value="" />
<auth-type value="PASSWORD" />
<key-file value="" />
<key-passphrase value="" />
</ssh-settings>
<ssl-settings>
<active value="false" />
<certificate-authority-file value="" />
<client-certificate-file value="" />
<client-key-file value="" />
</ssl-settings>
<details>
<charset value="UTF-8" />
<session-management value="true" />
<ddl-file-binding value="true" />
<database-logging value="true" />
<connect-automatically value="true" />
<restore-workspace value="true" />
<restore-workspace-deep value="false" />
<environment-type value="default" />
<connectivity-timeout value="30" />
<idle-time-to-disconnect value="30" />
<idle-time-to-disconnect-pool value="5" />
<credential-expiry-time value="10" />
<max-connection-pool-size value="7" />
<alternative-statement-delimiter value="" />
</details>
<debugger>
<compile-dependencies value="true" />
<tcp-driver-tunneling value="false" />
<tcp-host-address value="" />
<tcp-port-from value="4000" />
<tcp-port-to value="4999" />
</debugger>
<object-filters hide-empty-schemas="false" hide-pseudo-columns="false" hide-audit-columns="false">
<object-type-filter>
<object-type name="SCHEMA" enabled="true" />
<object-type name="USER" enabled="true" />
<object-type name="ROLE" enabled="true" />
<object-type name="PRIVILEGE" enabled="true" />
<object-type name="CHARSET" enabled="true" />
<object-type name="TABLE" enabled="true" />
<object-type name="VIEW" enabled="true" />
<object-type name="MATERIALIZED_VIEW" enabled="true" />
<object-type name="NESTED_TABLE" enabled="true" />
<object-type name="COLUMN" enabled="true" />
<object-type name="INDEX" enabled="true" />
<object-type name="CONSTRAINT" enabled="true" />
<object-type name="DATASET_TRIGGER" enabled="true" />
<object-type name="DATABASE_TRIGGER" enabled="true" />
<object-type name="SYNONYM" enabled="true" />
<object-type name="SEQUENCE" enabled="true" />
<object-type name="PROCEDURE" enabled="true" />
<object-type name="FUNCTION" enabled="true" />
<object-type name="PACKAGE" enabled="true" />
<object-type name="TYPE" enabled="true" />
<object-type name="TYPE_ATTRIBUTE" enabled="true" />
<object-type name="ARGUMENT" enabled="true" />
<object-type name="DIMENSION" enabled="true" />
<object-type name="CLUSTER" enabled="true" />
<object-type name="DBLINK" enabled="true" />
</object-type-filter>
<object-name-filters />
</object-filters>
</connection>
</connections>
<browser-settings>
<general>
<display-mode value="TABBED" />

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="SqlDialectMappings">
<file url="PROJECT" dialect="SQLite" />
</component>
</project>

@ -15,7 +15,6 @@ from pathlib import Path
# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/5.0/howto/deployment/checklist/
@ -27,7 +26,6 @@ DEBUG = True
ALLOWED_HOSTS = []
# Application definition
INSTALLED_APPS = [
@ -71,18 +69,20 @@ TEMPLATES = [
WSGI_APPLICATION = 'UGSdjangoProject.wsgi.application'
# Database
# https://docs.djangoproject.com/en/5.0/ref/settings/#databases
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': BASE_DIR / 'db.sqlite3',
'ENGINE': 'django.db.backends.mysql',
'NAME': 'ugssim',
'USER': 'ugssimuser',
'PASSWORD': 'Tradition2-Ransack-Retrial',
'HOST': 'localhost',
'PORT': '3306',
}
}
# Password validation
# https://docs.djangoproject.com/en/5.0/ref/settings/#auth-password-validators
@ -101,11 +101,10 @@ AUTH_PASSWORD_VALIDATORS = [
},
]
# Internationalization
# https://docs.djangoproject.com/en/5.0/topics/i18n/
LANGUAGE_CODE = 'de-de'
LANGUAGE_CODE = 'de'
TIME_ZONE = 'UTC'
@ -113,7 +112,6 @@ USE_I18N = True
USE_TZ = True
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/5.0/howto/static-files/
@ -126,4 +124,5 @@ DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
STATICFILES_DIRS = [os.path.join(BASE_DIR, "static")]
#DATE_INPUT_FORMATS = ['%d-%m-%Y']
DATE_FORMAT = '%Y-%m-%d'
DATE_INPUT_FORMATS = '%Y-%m-%d'

@ -1,42 +1,46 @@
from django import forms
from django.forms import DateInput
from .models import *
from ugssim.models import *
from ugssim.models import Address
from django import forms
''''
class AddressForm(forms.Form):
vorname = forms.CharField(max_length=255)
nachname = forms.CharField(max_length=255)
geburtstag = forms.DateField(widget=forms.SelectDateWidget)
street = forms.CharField(max_length=255)
hausnummer = forms.CharField(max_length=10)
postleitzahl = forms.CharField(max_length=5)
'''
class UGSModelForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
super(forms.ModelForm, self).__init__(*args, **kwargs)
# 'description should be the first field
# value = self.fields.pop('description')
# copy = self.fields.copy()
# new_pos = self.fields.keyOrder.index('b')
# self.fields = {'description': value}
# self.fields.update(copy)
# set 'form-control' as standard calls
for name, field in self.fields.items():
# if field.widget.__class__ == forms.widgets.TextInput:
if 'class' in field.widget.attrs:
field.widget.attrs['class'] += 'form-control'
else:
field.widget.attrs.update({'class': 'form-control'})
class AddressForm(forms.ModelForm):
class AddressForm(UGSModelForm):
class Meta:
model = Address
fields = '__all__'
# noinspection PyRedundantParentheses
widgets = {
'geburtstag': forms.DateInput(
format=('%Y-%m-%d'),
attrs={'class': 'form-control',
'placeholder': 'Wähle ein Datum',
'type': 'date'
}
)
}
def is_valid(self):
return True
format='%Y-%m-%d',
attrs={ # 'class': 'form-control',
'type': 'date'
}
),
}
class SummaryForm(forms.ModelForm):
class SummaryForm(UGSModelForm):
class Meta:
model = Summary
fields = '__all__'
@ -45,19 +49,19 @@ class SummaryForm(forms.ModelForm):
}
class SalesAreaTypeForm(forms.ModelForm):
class SalesAreaTypeForm(UGSModelForm):
class Meta:
model = SalesAreaType
fields = '__all__'
class SalesAreaForm(forms.ModelForm):
class SalesAreaForm(UGSModelForm):
class Meta:
model = SalesArea
fields = '__all__'
class CompanyDataForm(forms.ModelForm):
class CompanyDataForm(UGSModelForm):
class Meta:
model = CompanyData
fields = '__all__'

@ -1,4 +1,4 @@
# Generated by Django 5.0.1 on 2024-03-13 12:59
# Generated by Django 5.0.1 on 2024-03-14 13:26
import django.db.models.deletion
from django.db import migrations, models
@ -25,10 +25,12 @@ class Migration(migrations.Migration):
],
),
migrations.CreateModel(
name='SalesArea',
name='CompanyData',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('title', models.CharField(max_length=255)),
('website', models.URLField()),
('startDate', models.DateField()),
],
),
migrations.CreateModel(
@ -46,18 +48,11 @@ class Migration(migrations.Migration):
],
),
migrations.CreateModel(
name='CompanyData',
name='SalesArea',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('title', models.CharField(max_length=255)),
('website', models.URLField()),
('startDate', models.DateField()),
('salesArea', models.ManyToManyField(related_name='+', to='ugssim.salesarea')),
('type', models.ForeignKey(on_delete=django.db.models.deletion.RESTRICT, to='ugssim.salesareatype')),
],
),
migrations.AddField(
model_name='salesarea',
name='type',
field=models.ForeignKey(on_delete=django.db.models.deletion.RESTRICT, to='ugssim.salesareatype'),
),
]

@ -3,12 +3,14 @@ from datetime import date
from django import forms
from django.db import models
from UGSdjangoProject import settings
# Create your models here.
class Address(models.Model):
vorname = models.CharField(max_length=255)
nachname = models.CharField(max_length=255)
geburtstag: date = models.DateField()
geburtstag :date = models.DateField()
street = models.CharField(max_length=10)
hausnummer = models.CharField(max_length=255)
postleitzahl = models.CharField(max_length=5)

@ -1,5 +1,4 @@
<div class="container">
{% csrf_token %}
{% for field in companyDataForm %}
<div class="form-group">
<label for="{{ field.id_for_label }}">{{ field.label }}</label>

@ -1,19 +1,17 @@
<div class="container">
{% load read_dictonary %}
<!-- <form method="post" class="form-group">-->
{% csrf_token %}
{% for field in addressForm %}
<div class="form-group">
<label for="{{ field.id_for_label }}">{{ field.label }}</label>
<input class="form-control"
type="{{ field.field.widget.input_type }}"
name="{{ field.html_name }}"
id="{{ field.auto_id }}"
value="{{ field.value|default_if_none:"" }}"
>
{{ description }}
{% for field in myform %}
<div class="form-group">
{% if field.html_name == "description" %}
{% else %}
<label for="{{ field.id_for_label }}">{{ field.label }}</label>
{{field }}
{% endif %}
</div>
{% endfor %}
<button type="submit" class="btn btn-primary" name="addressButton">Submit</button>
<button type="submit" class="btn btn-primary" name="{{ modelname }}Button">Submit</button>
<!--</form> -->
</div>

@ -1,51 +1,31 @@
{% extends 'ugssim/ugssim.html' %}
{% load read_dictonary %}
{% block content %}
<form method="post" class="form-group">
<form method="post" class="form-group" action="/planungsparameter/">
{% csrf_token %}
<div class="accordion" id="accordionPlanning">
<div class="accordion-item">
<h2 class="accordion-header">
<button class="accordion-button" type="button" data-bs-toggle="collapse"
data-bs-target="#collapseOne"
aria-expanded="true" aria-controls="collapseOne">
Mandantendaten
</button>
</h2>
<div id="collapseOne" class="accordion-collapse collapse show" data-bs-parent="#accordionPlanning">
<div class="accordion-body">
{% include 'planungsparameter/mandantendaten.html' %}
{% define '' as show %}
{% for key,value in formlist.items %}
{% define value|lookup:'form' as myform %}
{% define value|lookup:'modelname' as modelname %}
{% define value|lookup:'description' as description %}
<div class="accordion-item">
<h2 class="accordion-header">
<button class="accordion-button" type="button" data-bs-toggle="collapse"
data-bs-target="#collapse{{ modelname }}"
aria-expanded="true" aria-controls="collapse{{ modelname }}">
{{ value|lookup:'heading' }}
</button>
</h2>
<div id="collapse{{ modelname }}" class="accordion-collapse collapse {{ show }}" data-bs-parent="#accordionPlanning">
<div class="accordion-body">
{% include 'planungsparameter/mandantendaten.html' %}
</div>
</div>
</div>
</div>
<div class="accordion-item">
<h2 class="accordion-header">
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse"
data-bs-target="#collapseTwo" aria-expanded="false" aria-controls="collapseTwo">
Kurzfassung
</button>
</h2>
<div id="collapseTwo" class="accordion-collapse collapse" data-bs-parent="#accordionPlanning">
<div class="accordion-body">
{% include 'planungsparameter/summary.html' %}
</div>
</div>
</div>
<div class="accordion-item">
<h2 class="accordion-header">
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse"
data-bs-target="#collapseThree" aria-expanded="false" aria-controls="collapseThree">
Unternehmensdaten
</button>
</h2>
<div id="collapseThree" class="accordion-collapse collapse" data-bs-parent="#accordionPlanning">
<div class="accordion-body">
{% include 'planungsparameter/companydata.html' %}
</div>
</div>
</div>
{% endfor %}
</div>
</form>
<!-- Add more sections here -->
{% endblock content %}
</div>

@ -1,6 +1,5 @@
<div class="container">
<form method="post" class="form-group">
{% csrf_token %}
{% for field in summaryForm %}
<div class="form-group">
<label for="{{ field.id_for_label }}">{{ field.label }}</label>
@ -8,5 +7,5 @@
</div>
{% endfor %}
<button type="submit" class="btn btn-primary" name="summaryButton">Submit</button>
</form>
</div>

@ -1,4 +1,5 @@
{% load static %}
{% load i18n l10n static read_dictonary %}
<script src="{% static 'bootstrap/js/bootstrap.bundle.js' %}"></script>
<!DOCTYPE html>
<html lang="de">
@ -18,5 +19,5 @@
{% include 'ugssim/navigation.html' %}
{% block content %}
{% endblock %}
<script src="{% static 'bootstrap/js/bootstrap.bundle.js' %}"></script>
</body>

@ -0,0 +1,28 @@
from django import template
from django.template.loader_tags import register
register = template.Library()
@register.filter(name='lookup')
def lookup(value, arg):
"""
Returns the value to key of a dictionary
:param value: The dictonary to perform the lookup on.
:param arg: The key used to perform the lookup.
:return: The value of the lookup operation.
"""
return value[arg]
@register.simple_tag
def define(val=None):
"""
Assigns the given value to a variable.
:param val: The value to assign. If not provided, the value will be None.
:return: The assigned value.
"""
return val

@ -5,14 +5,11 @@ from django.shortcuts import render
from .form import *
from .models import *
from django.forms.models import model_to_dict
import sys
from django.views.generic import TemplateView
# from ugssim.form import NameForm
# Create your views here.
def get_class(classname):
return getattr(sys.modules[__name__], classname)
def index(request):
@ -20,34 +17,44 @@ def index(request):
def planungsparameter(request):
addressForm = AddressForm()
summaryForm = SummaryForm()
companyDataForm = CompanyDataForm()
if request.method == "POST":
rp = request.POST
if 'addressButton' in rp:
addressForm = AddressForm(request.POST)
if addressForm.is_valid():
#Address.objects.create(**addressForm.cleaned_data)
addressForm.save()
elif 'summaryButton' in rp:
summaryForm = SummaryForm(request.POST)
if summaryForm.is_valid():
Summary.objects.update(**summaryForm.cleaned_data)
elif 'companyDataButton' in rp:
companyDataForm = CompanyDataForm(request.POST)
if companyDataForm.is_valid():
CompanyData.objects.update(**companyDataForm.cleaned_data)
else:
initial = model_to_dict(Address.objects.filter(id=1).first())
addressForm = AddressForm(initial=initial)
'''
Die Erzeugung der Webformulare soll dynamisch auf Basis der Model und Form Klassen
geschehen.
Dafür wird eine Liste mit den Klassenname der Models angelegt über die iteriert wird
Über die Funktion get_class(classname) erhält man das Klassenobjekt
modelclass für das Model
formclass für das Form
über diese wird dann iterierter.
Ein Formularfeld 'description' ist bei jedem Formular vorhanden, da die aber nicht
in der Datenbank /Model vorhanden ist. Daher wird dieses Feld entfernt (pop)
'''
formlist = {}
modellist = ['Address', 'Summary', 'CompanyData']
for modelname in modellist:
# globals()[ + 'Form'] = get_class( + 'Form')
modelclass = get_class(modelname)
formclass = get_class(modelname + 'Form')
if request.method == "POST":
rp = request.POST
if modelname + 'Button' in rp:
form = formclass(request.POST)
form.fields.pop('description')
if form.is_valid():
modelclass.objects.update(**form.cleaned_data)
else:
initial = {'description': 'Tester'}
# initial.update(model_to_dict(modelclass.objects.filter(id=1).first()))
form = formclass()
formpart = {
'modelname': modelname,
'form': form,
'heading': 'Mandatendaten2',
'description': 'Dict Descriptiopn'
}
formlist.update({modelname + "form": formpart})
context = {
'addressForm': addressForm,
'summaryForm': summaryForm,
'companyDataForm': companyDataForm
'formlist': formlist
}
return render(request, 'planungsparameter/planungsparameter.html', context)

Loading…
Cancel
Save