-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Feature/forms #10
Merged
Merged
Feature/forms #10
Changes from all commits
Commits
Show all changes
9 commits
Select commit
Hold shift + click to select a range
f5ab210
adjusted psycopg from c to binary
josihoppe 39882bb
added forms to forms.py
josihoppe 53fd6ef
added logic to render forms with their own page
josihoppe f1c5748
added missing bootstrap classes to forms
josihoppe 2fd161d
added view logic to submit and validate forms
josihoppe 2d660ce
adjusted clean methods of forms for custom validation
josihoppe 3ec6f2f
renamed view and changed doc string because of new functions
josihoppe d52df31
fixed rendering of radio buttons and checkboxes by using different wi…
josihoppe 9f40c65
explicitly loading the forms into the list by their names
josihoppe File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,235 @@ | ||
from django import forms | ||
|
||
|
||
class ElectricityConsumptionForm(forms.Form): | ||
household_members = forms.ChoiceField( | ||
label="Wie viele Personen leben in ihrem Haushalt?", | ||
choices=[ | ||
("", "bitte auswählen"), | ||
("1", "1"), | ||
("2", "2"), | ||
("3", "3"), | ||
("4", "4"), | ||
("5", "5"), | ||
], | ||
widget=forms.Select(attrs={"class": "form-select"}), | ||
) | ||
net_electricity_consumption1 = forms.IntegerField( | ||
label="Netto strom Verbrauch genau:", | ||
widget=forms.NumberInput(attrs={"class": "form-control"}), | ||
required=False, | ||
) | ||
net_electricity_consumption2 = forms.ChoiceField( | ||
label="oder ungefähr", | ||
choices=[ | ||
("", "bitte auswählen"), | ||
("high_consumption", "viel"), | ||
("medium_consumption", "mittel"), | ||
("low_consumption", "wenig"), | ||
], | ||
required=False, | ||
widget=forms.Select(attrs={"class": "form-select"}), | ||
) | ||
|
||
def clean(self): | ||
cleaned_data = super().clean() | ||
net_electricity_consumption1 = cleaned_data.get("net_electricity_consumption1") | ||
net_electricity_consumption2 = cleaned_data.get("net_electricity_consumption2") | ||
|
||
if not net_electricity_consumption1 and not net_electricity_consumption2: | ||
self.add_error( | ||
"net_electricity_consumption2", | ||
"Nettostromverbrauch entweder genau oder ungefähr eingeben.", | ||
) | ||
|
||
return cleaned_data | ||
|
||
|
||
class ElectricityGenerationForm(forms.Form): | ||
pv_owned = forms.BooleanField( | ||
label="Haben Sie eine PV-Anlage?", | ||
widget=forms.CheckboxInput(attrs={"class": "form-check-input"}), | ||
required=False, | ||
) | ||
installed_pv_power = forms.IntegerField( | ||
label="Wie groß ist die installierte Leistung?", | ||
widget=forms.NumberInput(attrs={"class": "form-control"}), | ||
required=False, | ||
) | ||
roof_cardinal_direction = forms.ChoiceField( | ||
label="In welcher Richtung ist ihr Haus ausgerichtet?", | ||
choices=[ | ||
("north", "Norden"), | ||
("east", "Osten"), | ||
("south_east", "Süd/Ost"), | ||
("south", "Süden"), | ||
("west", "Westen"), | ||
], | ||
widget=forms.RadioSelect, | ||
) | ||
roof_angle = forms.ChoiceField( | ||
label="Welchen Winkel hat das Dach?", | ||
choices=[ | ||
("north", "Flach"), | ||
("east", "Schräg"), | ||
], | ||
widget=forms.RadioSelect, | ||
) | ||
|
||
def clean(self): | ||
cleaned_data = super().clean() | ||
pv_owned = cleaned_data.get("pv_owned") | ||
installed_pv_power = cleaned_data.get("installed_pv_power") | ||
|
||
if pv_owned and not installed_pv_power: | ||
self.add_error("installed_pv_power", "Installierte Leistung eingeben.") | ||
if not pv_owned and installed_pv_power: | ||
self.add_error( | ||
"pv_owned", | ||
"Ankreuzen/auswählen, wenn eine installierte Leistung eingegeben wird.", | ||
) | ||
|
||
return cleaned_data | ||
|
||
|
||
class HeatGenerationForm(forms.Form): | ||
heat_output = forms.IntegerField( | ||
label="thermische Leistung der Heizungsanlage (Kessel)", | ||
widget=forms.NumberInput(attrs={"class": "form-control"}), | ||
required=False, | ||
) | ||
cannot_enter_info = forms.BooleanField( | ||
label="nicht vorhanden", | ||
required=False, | ||
widget=forms.CheckboxInput(attrs={"class": "form-check-input"}), | ||
) | ||
heat_pump_share = forms.MultipleChoiceField( | ||
label="Aus welchen Anteilen setzt sich ihre Wärmepumpe zusammen?", | ||
choices=[ | ||
("air", "Luft"), | ||
("water", "Wasser"), | ||
("brine", "Sole"), | ||
("no_heat_pump", "keine Wärmepumpe"), | ||
], | ||
widget=forms.CheckboxSelectMultiple, | ||
) | ||
|
||
def clean(self): | ||
cleaned_data = super().clean() | ||
heat_output = cleaned_data.get("heat_output") | ||
cannot_enter_info = cleaned_data.get("cannot_enter_info") | ||
|
||
if not heat_output and not cannot_enter_info: | ||
self.add_error("cannot_enter_info", "'Nicht vorhanden' auswählen.") | ||
if heat_output and cannot_enter_info: | ||
self.add_error( | ||
"heat_output", | ||
"Keine Leistung eintragen, wenn 'Nicht vorhanden'.", | ||
) | ||
|
||
return cleaned_data | ||
|
||
|
||
class HeatGenerationForm2(forms.Form): | ||
solar_thermal_system = forms.BooleanField( | ||
label="Haben Sie eine Solarthermieanlage?", | ||
widget=forms.CheckboxInput(attrs={"class": "form-check-input"}), | ||
required=False, | ||
) | ||
collector_surface = forms.IntegerField( | ||
label="Kollektorfläche", | ||
widget=forms.NumberInput(attrs={"class": "form-control"}), | ||
required=False, | ||
) | ||
collector_cardinal_direction = forms.ChoiceField( | ||
label="In welcher Richtung ist sie ausgerichtet?", | ||
choices=[ | ||
("north", "Norden"), | ||
("east", "Osten"), | ||
("south", "Süden"), | ||
("west", "Westen"), | ||
], | ||
widget=forms.RadioSelect, | ||
) | ||
roof_angle = forms.ChoiceField( | ||
label="Welchen Winkel hat das Dach?", | ||
choices=[ | ||
("north", "Flach"), | ||
("east", "Schräg"), | ||
], | ||
widget=forms.RadioSelect, | ||
) | ||
|
||
def clean(self): | ||
cleaned_data = super().clean() | ||
solar_thermal_system = cleaned_data.get("solar_thermal_system") | ||
collector_surface = cleaned_data.get("collector_surface") | ||
collector_cardinal_direction = cleaned_data.get("collector_cardinal_direction") | ||
|
||
if solar_thermal_system: | ||
if not collector_surface: | ||
self.add_error( | ||
"collector_surface", | ||
"Dieses Feld ausfüllen, wenn Solarthermieanlage vorhanden.", | ||
) | ||
if not collector_cardinal_direction: | ||
self.add_error( | ||
"collector_cardinal_direction", | ||
"Dieses Feld ausfüllen, wenn Solarthermieanlage vorhanden.", | ||
) | ||
elif collector_surface or collector_cardinal_direction: | ||
error_message = ( | ||
"Kollektorfläche und Ausrichtung auslassen, " | ||
"wenn keine Solarthermieanlage vorhanden." | ||
) | ||
raise forms.ValidationError(error_message) | ||
|
||
return cleaned_data | ||
|
||
|
||
class HeatConsumptionForm(forms.Form): | ||
heating_requirement1 = forms.IntegerField( | ||
label="Jahresheizbedarf pro m² genau:", | ||
widget=forms.NumberInput(attrs={"class": "form-control"}), | ||
initial=1, | ||
required=False, | ||
) | ||
heating_requirement2 = forms.ChoiceField( | ||
label="ungefähr:", | ||
choices=[ | ||
("high_consumption", "viel"), | ||
("medium_consumption", "mittel"), | ||
("low_consumption", "wenig"), | ||
], | ||
required=False, | ||
widget=forms.Select(attrs={"class": "form-select"}), | ||
) | ||
|
||
def clean(self): | ||
cleaned_data = super().clean() | ||
heating_requirement1 = cleaned_data.get("heating_requirement1") | ||
heating_requirement2 = cleaned_data.get("heating_requirement2") | ||
|
||
if not heating_requirement1 and not heating_requirement2: | ||
self.add_error( | ||
"heating_requirement2", | ||
"Jahresheizbedarf entweder genau oder ungefähr eingeben.", | ||
) | ||
|
||
return cleaned_data | ||
|
||
|
||
class HeatStorageForm(forms.Form): | ||
buffer_storage_owned = forms.BooleanField( | ||
label="Ist ein Pufferspeicher vorhanden?", | ||
widget=forms.CheckboxInput(attrs={"class": "form-check-input"}), | ||
required=False, | ||
) | ||
|
||
|
||
class ElectricityStorageForm(forms.Form): | ||
battery_owned = forms.BooleanField( | ||
label="Ist eine Batterie vorhanden?", | ||
widget=forms.CheckboxInput(attrs={"class": "form-check-input"}), | ||
required=False, | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,9 @@ | ||
from django.urls import path | ||
|
||
from . import views | ||
|
||
app_name = "heat" | ||
|
||
urlpatterns = [] | ||
urlpatterns = [ | ||
path("forms/", views.handle_forms, name="forms"), | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,54 @@ | ||
# Create your views here. | ||
from django.http import HttpResponse | ||
from django.shortcuts import render | ||
|
||
from .forms import ElectricityConsumptionForm | ||
from .forms import ElectricityGenerationForm | ||
from .forms import ElectricityStorageForm | ||
from .forms import HeatConsumptionForm | ||
from .forms import HeatGenerationForm | ||
from .forms import HeatGenerationForm2 | ||
from .forms import HeatStorageForm | ||
|
||
|
||
def handle_forms(request): | ||
""" | ||
This view renders a list which contains all the forms for the app (GET) | ||
or it gets all the responses from the submits and validates the forms (POST). | ||
|
||
Parameters: | ||
- request: HttpRequest object representing the client's request. | ||
|
||
Returns: | ||
- HttpResponse object containing the rendered template with the list | ||
of form instances. | ||
- HttpResponse object indicating successful form processing if all | ||
forms are valid. | ||
""" | ||
form_classes = [ | ||
ElectricityConsumptionForm, | ||
ElectricityGenerationForm, | ||
ElectricityStorageForm, | ||
HeatGenerationForm, | ||
HeatGenerationForm2, | ||
HeatConsumptionForm, | ||
HeatStorageForm, | ||
] | ||
|
||
if request.method == "POST": | ||
# Instantiate form instances with submitted data | ||
form_instances = [f(request.POST) for f in form_classes] | ||
all_valid = all(form.is_valid() for form in form_instances) | ||
|
||
context = {"form_instances": form_instances} | ||
if all_valid: | ||
for form in form_instances: | ||
print(form.cleaned_data) # noqa: T201 | ||
# logic to handle form data | ||
return HttpResponse("All forms are valid and have been processed.") | ||
|
||
else: | ||
context = { | ||
"form_instances": [f() for f in form_classes], | ||
} | ||
|
||
return render(request, "pages/heat_forms.html", context) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
{% extends "base.html" %} | ||
|
||
{% block content %} | ||
<form method="post" action="{% url 'heat:forms' %}"> | ||
{% csrf_token %} | ||
{% for form in form_instances %} | ||
<div class="mb-3"> | ||
{{ form.as_p }} | ||
<hr /> | ||
</div> | ||
{% endfor %} | ||
<button type="submit" class="btn btn-primary">Save All</button> | ||
</form> | ||
{% endblock content %} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here, you could check if some are not valid first, and return view with forms back to user showing the errors in the form.