add form labels, form errors, log action

This commit is contained in:
2022-04-02 08:46:58 +00:00
parent 5841eb363e
commit 96805b2cc1
7 changed files with 162 additions and 72 deletions

24
fet2020/fet2020/utils.py Normal file
View File

@@ -0,0 +1,24 @@
# util functions for all apps
from django.contrib.admin.models import ADDITION, CHANGE, LogEntry
from django.contrib.admin.utils import construct_change_message
from django.contrib.contenttypes.models import ContentType
def add_log_action(request, form, app_label, model, add=True):
obj = form.save()
content_type = ContentType.objects.get(app_label=app_label, model=model)
change_message = construct_change_message(form, None, add)
if add:
action_flag = ADDITION
else:
action_flag = CHANGE
LogEntry.objects.log_action(
user_id=request.user.pk,
content_type_id=content_type.pk,
object_id=obj.pk,
object_repr=str(obj),
action_flag=action_flag,
change_message=change_message,
)

View File

@@ -122,7 +122,7 @@ class TaskCreateForm(forms.ModelForm):
return cleaned_data return cleaned_data
class TaskUpdateForm(TaskCreateForm): class TaskUpdateForm(forms.ModelForm):
class Meta: class Meta:
model = Task model = Task
@@ -146,6 +146,18 @@ class TaskUpdateForm(TaskCreateForm):
"task_list": HiddenInput, "task_list": HiddenInput,
} }
def __init__(self, *args, **kwargs):
if "task_list" in kwargs:
task_list = kwargs.pop("task_list")
else:
task_list = None
super().__init__(*args, **kwargs) # to get the self.fields set
self.fields["assigned_to"].empty_label = "Alle"
if task_list:
qs = TaskList.objects.get(id=task_list.id).users
self.fields["assigned_to"].queryset = qs.order_by("username")
class DocumentCreateForm(forms.ModelForm): class DocumentCreateForm(forms.ModelForm):
class Meta: class Meta:

View File

@@ -1,11 +1,8 @@
import logging import logging
from collections import deque from collections import deque
from django.contrib.admin.models import ADDITION, CHANGE, LogEntry
from django.contrib.admin.utils import construct_change_message
from django.contrib.auth.mixins import LoginRequiredMixin from django.contrib.auth.mixins import LoginRequiredMixin
from django.contrib.auth.models import User from django.contrib.auth.models import User
from django.contrib.contenttypes.models import ContentType
from django.shortcuts import render from django.shortcuts import render
from django.views.generic.detail import DetailView from django.views.generic.detail import DetailView
from django.views.generic.edit import CreateView, UpdateView from django.views.generic.edit import CreateView, UpdateView
@@ -15,6 +12,7 @@ from django.utils import timezone
from authentications.decorators import authenticated_user from authentications.decorators import authenticated_user
from documents.api import get_pad_link from documents.api import get_pad_link
from documents.etherpadlib import add_ep_cookie from documents.etherpadlib import add_ep_cookie
from fet2020.utils import add_log_action
from intern.models import Topic from intern.models import Topic
from .forms import DocumentCreateForm, TaskCreateForm, TaskUpdateForm from .forms import DocumentCreateForm, TaskCreateForm, TaskUpdateForm
from .models import Document, Task, TaskList from .models import Document, Task, TaskList
@@ -77,42 +75,17 @@ def index(request):
return render(request, "tasks/index.html", context) return render(request, "tasks/index.html", context)
def add_log_action(request, form, add=True):
obj = form.save()
content_type = ContentType.objects.get(app_label="tasks", model="task")
change_message = construct_change_message(form, None, add)
if add:
action_flag = ADDITION
else:
action_flag = CHANGE
LogEntry.objects.log_action(
user_id=request.user.pk,
content_type_id=content_type.pk,
object_id=obj.pk,
object_repr=str(obj),
action_flag=action_flag,
change_message=change_message,
)
class TaskCreate(LoginRequiredMixin, CreateView): class TaskCreate(LoginRequiredMixin, CreateView):
model = Task model = Task
success_url = reverse_lazy("tasks:index") success_url = reverse_lazy("tasks:index")
template_name = "tasks/task_create.html" template_name = "tasks/task_create.html"
form_class = TaskCreateForm form_class = TaskCreateForm
user = None
def form_valid(self, form): def form_valid(self, form):
form.instance.created_by = self.request.user form.instance.created_by = self.request.user
add_log_action(self.request, form, True) add_log_action(self.request, form, "tasks", "task", True)
return super().form_valid(form) return super().form_valid(form)
def get_initial(self):
self.user = self.request.user
def get_form_kwargs(self): def get_form_kwargs(self):
kwargs = super().get_form_kwargs() kwargs = super().get_form_kwargs()
kwargs["user"] = self.request.user kwargs["user"] = self.request.user
@@ -124,15 +97,30 @@ class TaskUpdate(LoginRequiredMixin, UpdateView):
template_name = "tasks/task_update.html" template_name = "tasks/task_update.html"
form_class = TaskUpdateForm form_class = TaskUpdateForm
pk = None task_id = None
task_list = None
def form_valid(self, form): def form_valid(self, form):
add_log_action(self.request, form, False) add_log_action(self.request, form, "tasks", "task", False)
return super().form_valid(form) return super().form_valid(form)
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context["task_list"] = self.task_list
return context
def get_form_kwargs(self):
kwargs = super().get_form_kwargs()
kwargs["task_list"] = self.task_list
return kwargs
def get_initial(self):
self.task_id = self.kwargs.get("pk")
self.task_list = Task.objects.get(id=self.task_id).task_list
def get_success_url(self): def get_success_url(self):
kwargs = { kwargs = {
"pk": self.kwargs.get("pk"), "pk": self.task_id,
} }
return reverse("tasks:task-detail", kwargs=kwargs) return reverse("tasks:task-detail", kwargs=kwargs)
@@ -156,9 +144,7 @@ class TaskDetail(LoginRequiredMixin, DetailView):
context = super().get_context_data(**kwargs) context = super().get_context_data(**kwargs)
docus = Document.objects.filter(task__id=self.object.id).order_by("-date") docus = Document.objects.filter(task__id=self.object.id).order_by("-date")
documents = deque([]) documents = deque([])
# list of etherpad url-link of any documents # list of etherpad url-link of any documents
for elem in docus: for elem in docus:
documents.append( documents.append(
@@ -182,17 +168,17 @@ class DocumentCreate(LoginRequiredMixin, CreateView):
task_id = None task_id = None
def form_valid(self, form):
form.instance.created_by = self.request.user
add_log_action(self.request, form, "tasks", "document", True)
return super().form_valid(form)
def get_initial(self): def get_initial(self):
self.task_id = self.kwargs.get("pk") self.task_id = self.kwargs.get("pk")
task = Task.objects.get(pk=self.task_id)
context = {
"task": task,
}
return context
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs) context = super().get_context_data(**kwargs)
context["task_id"] = self.task_id context["task"] = Task.objects.get(pk=self.task_id)
return context return context

View File

@@ -10,17 +10,35 @@
<form action="" method="POST" class="w-full max-w-prose sm:px-28 sm:py-4 grid grid-cols-1 gap-y-3 sm:gap-y-6 text-gray-900"> <form action="" method="POST" class="w-full max-w-prose sm:px-28 sm:py-4 grid grid-cols-1 gap-y-3 sm:gap-y-6 text-gray-900">
{% csrf_token %} {% csrf_token %}
{% if form.non_field_errors %}
<div class="alert alert-danger">
<i class="alert-icon fas fa-check-circle"></i>
<h2 class="alert-title">Fehler:</h2>
<div class="alert-body">{{ form.non_field_errors }}</div>
</div>
{% endif %}
<label class="block"> <label class="block">
<span class="text-gray-700 dark:text-gray-200">Titel</span> <span class="text-gray-700 dark:text-gray-200">{{ form.title.label }}</span>
{% if form.title.errors %}
<div class="alert alert-danger">
<div class="alert-body">{{ form.title.errors }}</div>
</div>
{% endif %}
<input type="text" id="id_title" name="title" class="mt-1 block w-full rounded-md border-gray-300 dark:border-none shadow-sm focus:border-none focus:ring focus:ring-blue-200 dark:focus:ring-sky-700 focus:ring-opacity-50" required> <input type="text" id="id_title" name="title" class="mt-1 block w-full rounded-md border-gray-300 dark:border-none shadow-sm focus:border-none focus:ring focus:ring-blue-200 dark:focus:ring-sky-700 focus:ring-opacity-50" required>
</label> </label>
<label> <label>
<span class="text-gray-700 dark:text-gray-200">Datum</span> <span class="text-gray-700 dark:text-gray-200">{{ form.date.label }}</span>
{% if form.date.errors %}
<div class="alert alert-danger">
<div class="alert-body">{{ form.date.errors }}</div>
</div>
{% endif %}
<input type="date" id="id_date" name="date" class="block w-full mt-1 rounded-md border-gray-300 dark:border-none shadow-sm focus:border-none focus:ring focus:ring-blue-200 dark:focus:ring-sky-700 focus:ring-opacity-50"> <input type="date" id="id_date" name="date" class="block w-full mt-1 rounded-md border-gray-300 dark:border-none shadow-sm focus:border-none focus:ring focus:ring-blue-200 dark:focus:ring-sky-700 focus:ring-opacity-50">
</label> </label>
<input type="hidden" name="task" value="{{ task_id }}" id="id_task"> <input type="hidden" name="task" value="{{ task.id }}" id="id_task">
<input type="submit" class="block btn btn-primary" value="Hinzufügen"> <input type="submit" class="block btn btn-primary" value="Hinzufügen">
</form> </form>

View File

@@ -85,6 +85,7 @@
{% if tasks %} {% if tasks %}
<form action="" method="post"> <form action="" method="post">
{% csrf_token %} {% csrf_token %}
{% regroup tasks by task_list as section_list %} {% regroup tasks by task_list as section_list %}
{% for group in section_list %} {% for group in section_list %}
<h3>{{ group.grouper }}</h3> <h3>{{ group.grouper }}</h3>
@@ -102,13 +103,13 @@
{% endif %} {% endif %}
</label> </label>
{% endfor %} {% endfor %}
{% endfor %}
<div class="flex flex-col md:flex-row gap-y-2 md:gap-y-0 md:gap-x-2 lg:justify-end mt-4"> <div class="flex flex-col md:flex-row gap-y-2 md:gap-y-0 md:gap-x-2 lg:justify-end mt-4">
<input type="submit" name="btn_checkbox" value="Tasks abschließen" class="btn btn-error block md:flex-grow lg:flex-grow-0"> <input type="submit" name="btn_checkbox" value="Tasks abschließen" class="btn btn-error block md:flex-grow lg:flex-grow-0">
<a href="{% url 'tasks:task-create' %}" class="btn btn-primary block md:flex-grow lg:flex-grow-0"><i class="fas fa-plus-square mr-2"></i>Task hinzufügen</a> <a href="{% url 'tasks:task-create' %}" class="btn btn-primary block md:flex-grow lg:flex-grow-0"><i class="fas fa-plus-square mr-2"></i>Task hinzufügen</a>
</div> </div>
{% endfor %}
</form> </form>
{% else %} {% else %}
keine Tasks in dieser Liste für dich. keine Tasks in dieser Liste für dich.

View File

@@ -9,16 +9,32 @@
<div class="w-full h-full flex-1 flex justify-center items-center"> <div class="w-full h-full flex-1 flex justify-center items-center">
<form action="" method="POST" class="w-full max-w-prose sm:px-28 sm:py-4 grid grid-cols-1 gap-y-3 sm:gap-y-6 text-gray-900"> <form action="" method="POST" class="w-full max-w-prose sm:px-28 sm:py-4 grid grid-cols-1 gap-y-3 sm:gap-y-6 text-gray-900">
{% csrf_token %} {% csrf_token %}
{% if form.non_field_errors %}
<div class="alert alert-danger">
<i class="alert-icon fas fa-check-circle"></i>
<h2 class="alert-title">Fehler:</h2>
<div class="alert-body">{{ form.non_field_errors }}</div>
</div>
{% endif %}
<label class="block"> <label class="block">
<span class="text-gray-700 dark:text-gray-200">Titel</span> <span class="text-gray-700 dark:text-gray-200">{{ form.title.label }}</span>
{% if form.title.errors %}
<div class="alert alert-danger">
<div class="alert-body">{{ form.title.errors }}</div>
</div>
{% endif %}
<input type="text" id="id_title" name="title" class="mt-1 block w-full rounded-md border-gray-300 dark:border-none shadow-sm focus:border-none focus:ring focus:ring-blue-200 dark:focus:ring-sky-700 focus:ring-opacity-50" required> <input type="text" id="id_title" name="title" class="mt-1 block w-full rounded-md border-gray-300 dark:border-none shadow-sm focus:border-none focus:ring focus:ring-blue-200 dark:focus:ring-sky-700 focus:ring-opacity-50" required>
</label> </label>
<label class="block">
<span class="text-gray-700 dark:text-gray-200">Kürzel für den URL-Link</span>
<input type="text" id="id_shortterm" name="shortterm" class="mt-1 block w-full rounded-md border-gray-300 dark:border-none shadow-sm focus:border-none focus:ring focus:ring-blue-200 dark:focus:ring-sky-700 focus:ring-opacity-50" required>
</label>
<label> <label>
<span class="text-gray-700 dark:text-gray-200">Task-Gruppe</span> <span class="text-gray-700 dark:text-gray-200">{{ form.task_list.label }}</span>
{% if form.task_list.errors %}
<div class="alert alert-danger">
<div class="alert-body">{{ form.task_list.errors }}</div>
</div>
{% endif %}
<select id="id_task_list" name="task_list" class="block w-full mt-1 rounded-md border-gray-300 dark:border-none shadow-sm focus:border-none focus:ring focus:ring-blue-200 dark:focus:ring-sky-700 focus:ring-opacity-50" required> <select id="id_task_list" name="task_list" class="block w-full mt-1 rounded-md border-gray-300 dark:border-none shadow-sm focus:border-none focus:ring focus:ring-blue-200 dark:focus:ring-sky-700 focus:ring-opacity-50" required>
{% for elem in form.task_list %} {% for elem in form.task_list %}
{% if forloop.first %} {% if forloop.first %}
@@ -29,12 +45,24 @@
{% endfor %} {% endfor %}
</select> </select>
</label> </label>
<label> <label>
<span class="text-gray-700 dark:text-gray-200">Fähigkeitsdatum</span> <span class="text-gray-700 dark:text-gray-200">{{ form.due_date.label }}</span>
{% if form.due_date.errors %}
<div class="alert alert-danger">
<div class="alert-body">{{ form.due_date.errors }}</div>
</div>
{% endif %}
<input type="date" id="id_due_date" name="due_date" class="block w-full mt-1 rounded-md border-gray-300 dark:border-none shadow-sm focus:border-none focus:ring focus:ring-blue-200 dark:focus:ring-sky-700 focus:ring-opacity-50"> <input type="date" id="id_due_date" name="due_date" class="block w-full mt-1 rounded-md border-gray-300 dark:border-none shadow-sm focus:border-none focus:ring focus:ring-blue-200 dark:focus:ring-sky-700 focus:ring-opacity-50">
</label> </label>
<label> <label>
<span class="text-gray-700 dark:text-gray-200">Zuweisen an</span> <span class="text-gray-700 dark:text-gray-200">{{ form.assigned_to.label }}</span>
{% if form.assigned_to.errors %}
<div class="alert alert-danger">
<div class="alert-body">{{ form.assigned_to.errors }}</div>
</div>
{% endif %}
<select id="id_assigned_to" name="assigned_to" class="block w-full mt-1 rounded-md border-gray-300 dark:border-none shadow-sm focus:border-none focus:ring focus:ring-blue-200 dark:focus:ring-sky-700 focus:ring-opacity-50"> <select id="id_assigned_to" name="assigned_to" class="block w-full mt-1 rounded-md border-gray-300 dark:border-none shadow-sm focus:border-none focus:ring focus:ring-blue-200 dark:focus:ring-sky-700 focus:ring-opacity-50">
{% for elem in form.assigned_to %} {% for elem in form.assigned_to %}
{% if forloop.first %} {% if forloop.first %}
@@ -43,9 +71,9 @@
{{ elem }} {{ elem }}
{% endif %} {% endif %}
{% endfor %} {% endfor %}
</select> </select>
</label> </label>
<input type="submit" class="block btn btn-primary" value="Hinzufügen"> <input type="submit" class="block btn btn-primary" value="Hinzufügen">
</form> </form>

View File

@@ -9,8 +9,22 @@
<div class="w-full h-full flex-1 flex justify-center items-center"> <div class="w-full h-full flex-1 flex justify-center items-center">
<form action="" method="POST" class="w-full max-w-prose sm:px-28 sm:py-4 grid grid-cols-1 gap-y-3 sm:gap-y-6 text-gray-900"> <form action="" method="POST" class="w-full max-w-prose sm:px-28 sm:py-4 grid grid-cols-1 gap-y-3 sm:gap-y-6 text-gray-900">
{% csrf_token %} {% csrf_token %}
{% if form.non_field_errors %}
<div class="alert alert-danger">
<i class="alert-icon fas fa-check-circle"></i>
<h2 class="alert-title">Fehler:</h2>
<div class="alert-body">{{ form.non_field_errors }}</div>
</div>
{% endif %}
<label> <label>
<span class="text-gray-700 dark:text-gray-200">Zuweisen an</span> <span class="text-gray-700 dark:text-gray-200">{{ form.assigned_to.label }}</span>
{% if form.assigned_to.errors %}
<div class="alert alert-danger">
<div class="alert-body">{{ form.assigned_to.errors }}</div>
</div>
{% endif %}
<select id="id_assigned_to" name="assigned_to" class="block w-full mt-1 rounded-md border-gray-300 dark:border-none shadow-sm focus:border-none focus:ring focus:ring-blue-200 dark:focus:ring-sky-700 focus:ring-opacity-50"> <select id="id_assigned_to" name="assigned_to" class="block w-full mt-1 rounded-md border-gray-300 dark:border-none shadow-sm focus:border-none focus:ring focus:ring-blue-200 dark:focus:ring-sky-700 focus:ring-opacity-50">
{% for elem in form.assigned_to %} {% for elem in form.assigned_to %}
{% if forloop.first %} {% if forloop.first %}
@@ -23,10 +37,17 @@
</label> </label>
<label> <label>
<span class="text-gray-700 dark:text-gray-200">Fähigkeitsdatum</span> <span class="text-gray-700 dark:text-gray-200">{{ form.due_date.label }}</span>
{% if form.due_date.errors %}
<div class="alert alert-danger">
<div class="alert-body">{{ form.due_date.errors }}</div>
</div>
{% endif %}
<input type="date" id="id_due_date" name="due_date" value="{{ task.due_date|date:"Y-m-d" }}" class="block w-full mt-1 rounded-md border-gray-300 dark:border-none shadow-sm focus:border-none focus:ring focus:ring-blue-200 dark:focus:ring-sky-700 focus:ring-opacity-50"> <input type="date" id="id_due_date" name="due_date" value="{{ task.due_date|date:"Y-m-d" }}" class="block w-full mt-1 rounded-md border-gray-300 dark:border-none shadow-sm focus:border-none focus:ring focus:ring-blue-200 dark:focus:ring-sky-700 focus:ring-opacity-50">
</label> </label>
<input type="hidden" name="task_list" value="{{ task_list.id }}" id="id_task_list">
<input type="submit" class="block btn btn-primary" value="Hinzufügen"> <input type="submit" class="block btn btn-primary" value="Hinzufügen">
</form> </form>