update module
This commit is contained in:
parent
41e8bce03c
commit
08bf161f09
7 changed files with 114 additions and 6 deletions
|
|
@ -55,6 +55,11 @@ class Question(models.Model):
|
|||
body = models.TextField()
|
||||
member = models.ForeignKey(Member, related_name="questions", on_delete=models.CASCADE)
|
||||
created_at = models.DateTimeField(auto_now_add=True)
|
||||
# asker metadata
|
||||
asker_first_name = models.CharField(max_length=150, blank=True)
|
||||
asker_last_name = models.CharField(max_length=150, blank=True)
|
||||
asker_city = models.CharField(max_length=150, blank=True)
|
||||
asker_email = models.EmailField(blank=True)
|
||||
|
||||
class Meta:
|
||||
verbose_name = "Frage"
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ urlpatterns = [
|
|||
path("gemeinden/<slug:slug>/", views.public_body_detail, name="public_body_detail"),
|
||||
path("mitglieder/", views.members, name="members"),
|
||||
path("mitglieder/<int:pk>/", views.member_detail, name="member_detail"),
|
||||
path("mitglieder/<int:pk>/frage/stellen", views.ask_question, name="ask_question"),
|
||||
path("parteien/", views.parties, name="parties"),
|
||||
path("parteien/<int:pk>/", views.party_detail, name="party_detail"),
|
||||
path("fragen/", views.questions, name="questions"),
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
from django.shortcuts import render, get_object_or_404
|
||||
from django.shortcuts import render, get_object_or_404, redirect
|
||||
from django.contrib import messages
|
||||
from .models import PublicBody, Party, Member, Question, Vote
|
||||
|
||||
|
||||
|
|
@ -39,6 +40,34 @@ def member_detail(request, pk: int):
|
|||
)
|
||||
|
||||
|
||||
def ask_question(request, pk: int):
|
||||
member = get_object_or_404(Member, pk=pk)
|
||||
if request.method != "POST":
|
||||
return redirect("member_detail", pk=member.pk)
|
||||
|
||||
title = request.POST.get("title", "").strip()
|
||||
asker_first_name = request.POST.get("asker_first_name", "").strip()
|
||||
asker_last_name = request.POST.get("asker_last_name", "").strip()
|
||||
asker_city = request.POST.get("asker_city", "").strip()
|
||||
asker_email = request.POST.get("asker_email", "").strip()
|
||||
|
||||
if not title or not asker_first_name or not asker_last_name or not asker_city or not asker_email:
|
||||
messages.error(request, "Bitte alle Pflichtfelder ausfüllen.")
|
||||
return redirect("member_detail", pk=member.pk)
|
||||
|
||||
Question.objects.create(
|
||||
title=title,
|
||||
body=title,
|
||||
member=member,
|
||||
asker_first_name=asker_first_name,
|
||||
asker_last_name=asker_last_name,
|
||||
asker_city=asker_city,
|
||||
asker_email=asker_email,
|
||||
)
|
||||
messages.success(request, "Frage wurde eingereicht.")
|
||||
return redirect("member_detail", pk=member.pk)
|
||||
|
||||
|
||||
def parties(request):
|
||||
items = Party.objects.all()
|
||||
return render(request, "council/parties.html", {"items": items})
|
||||
|
|
|
|||
|
|
@ -31,6 +31,8 @@
|
|||
mkdir -p $out/share/fragdenrat
|
||||
# Project code
|
||||
cp -r "${./fragdenrat}/." $out/share/fragdenrat/
|
||||
# Django app: council
|
||||
cp -r ${./council} $out/share/fragdenrat/council
|
||||
# Django manage helper
|
||||
install -Dm755 ${./manage.py} $out/bin/fragdenrat-manage
|
||||
# Templates and static assets
|
||||
|
|
|
|||
|
|
@ -1,7 +1,10 @@
|
|||
from django.contrib import admin
|
||||
from django.urls import path, include
|
||||
from django.views.generic import TemplateView
|
||||
|
||||
urlpatterns = [
|
||||
path("admin/", admin.site.urls),
|
||||
path("impressum", TemplateView.as_view(template_name="impressum.html"), name="impressum"),
|
||||
path("datenschutz", TemplateView.as_view(template_name="datenschutz.html"), name="datenschutz"),
|
||||
path("", include("council.urls")),
|
||||
]
|
||||
|
|
@ -39,6 +39,16 @@
|
|||
{% block content %}{% endblock %}
|
||||
</main>
|
||||
|
||||
<footer class="border-top bg-white py-3 mt-4">
|
||||
<div class="container d-flex justify-content-between">
|
||||
<span class="text-muted">© {{ now|date:'Y' }} FragDenRat</span>
|
||||
<nav>
|
||||
<a href="{% url 'impressum' %}" class="text-muted me-3">Impressum</a>
|
||||
<a href="{% url 'datenschutz' %}" class="text-muted">Datenschutz</a>
|
||||
</nav>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
<script src="{% static 'js/bootstrap.bundle.min.js' %}"></script>
|
||||
{% block extra_js %}{% endblock %}
|
||||
</body>
|
||||
|
|
|
|||
|
|
@ -1,11 +1,26 @@
|
|||
{% extends "base.html" %}
|
||||
{% block title %}{{ member }} – Stadträt:in{% endblock %}
|
||||
{% block content %}
|
||||
<h2 class="mb-1">{{ member.first_name }} {{ member.last_name }}</h2>
|
||||
<p class="text-muted mb-3">
|
||||
<div class="d-flex justify-content-between align-items-start">
|
||||
<div>
|
||||
<h2 class="mb-1">{{ member.first_name }} {{ member.last_name }}</h2>
|
||||
<p class="text-muted mb-3">
|
||||
{% if member.public_body %}in <a href="{% url 'public_body_detail' slug=member.public_body.slug %}">{{ member.public_body.name }}</a>{% endif %}
|
||||
{% if member.party %} • {{ member.party }} (<a href="{% url 'party_detail' pk=member.party.id %}">Profil</a>){% endif %}
|
||||
</p>
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<button class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#askQuestionModal">Frage stellen</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% if messages %}
|
||||
<div class="mt-2">
|
||||
{% for message in messages %}
|
||||
<div class="alert alert-{{ message.tags|default:'info' }}">{{ message }}</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<h3 class="mt-4">Fragen an {{ member.first_name }}</h3>
|
||||
<ul class="list-group mb-4">
|
||||
|
|
@ -33,4 +48,47 @@
|
|||
<li class="list-group-item">Keine Abstimmungen.</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
|
||||
<!-- Ask Question Modal -->
|
||||
<div class="modal fade" id="askQuestionModal" tabindex="-1" aria-labelledby="askQuestionModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title" id="askQuestionModalLabel">Frage an {{ member.first_name }} {{ member.last_name }}</h5>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Schließen"></button>
|
||||
</div>
|
||||
<form method="post" action="{% url 'ask_question' pk=member.id %}">
|
||||
{% csrf_token %}
|
||||
<div class="modal-body">
|
||||
<div class="mb-3">
|
||||
<label for="title" class="form-label">Frage</label>
|
||||
<input type="text" class="form-control" id="title" name="title" required>
|
||||
</div>
|
||||
<div class="row g-2">
|
||||
<div class="col-6">
|
||||
<label for="asker_first_name" class="form-label">Vorname</label>
|
||||
<input type="text" class="form-control" id="asker_first_name" name="asker_first_name" required>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<label for="asker_last_name" class="form-label">Name</label>
|
||||
<input type="text" class="form-control" id="asker_last_name" name="asker_last_name" required>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mb-3 mt-2">
|
||||
<label for="asker_city" class="form-label">Wohnort</label>
|
||||
<input type="text" class="form-control" id="asker_city" name="asker_city" required>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="asker_email" class="form-label">E-Mail</label>
|
||||
<input type="email" class="form-control" id="asker_email" name="asker_email" required>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Abbrechen</button>
|
||||
<button type="submit" class="btn btn-primary">Senden</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
Loading…
Add table
Add a link
Reference in a new issue