Document upload

* adds document upload form
* refactors modal form templates into form classes
* adds document upload route to intervention routes of urls.py
This commit is contained in:
mipel 2021-07-26 15:16:16 +02:00
parent 1d4be22da5
commit 1ff02c30a6
10 changed files with 106 additions and 41 deletions

View File

@ -48,6 +48,7 @@ class NewPaymentForm(BaseModalForm):
) )
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
self.template = "modal/modal_form.html"
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
self.intervention = self.instance self.intervention = self.instance
self.form_title = _("Payment") self.form_title = _("Payment")

View File

@ -125,9 +125,9 @@ def new_payment_view(request: HttpRequest, intervention_id: str):
Returns: Returns:
""" """
template = "modal/modal_form.html"
intervention = get_object_or_404(Intervention, id=intervention_id) intervention = get_object_or_404(Intervention, id=intervention_id)
form = NewPaymentForm(request.POST or None, instance=intervention, user=request.user) form = NewPaymentForm(request.POST or None, instance=intervention, user=request.user)
template = form.template
if request.method == "POST": if request.method == "POST":
if form.is_valid(): if form.is_valid():
payment = form.save() payment = form.save()
@ -163,9 +163,9 @@ def payment_remove_view(request: HttpRequest, id: str):
Returns: Returns:
""" """
template = "modal/modal_form.html"
payment = get_object_or_404(Payment, id=id) payment = get_object_or_404(Payment, id=id)
form = RemoveModalForm(request.POST or None, instance=payment, user=request.user) form = RemoveModalForm(request.POST or None, instance=payment, user=request.user)
template = form.template
if request.method == "POST": if request.method == "POST":
if form.is_valid(): if form.is_valid():
form.save() form.save()

View File

@ -12,12 +12,10 @@
</div> </div>
<div class="col-sm-6"> <div class="col-sm-6">
<div class="d-flex justify-content-end"> <div class="d-flex justify-content-end">
<a href="{% url 'doc-new' %}" title="{% trans 'Add new document' %}"> <button class="btn btn-outline-default btn-modal" data-form-url="{% url 'intervention:new-doc' intervention.id %}" title="{% trans 'Add new document' %}">
<button class="btn btn-outline-default ">
{% fa5_icon 'plus' %} {% fa5_icon 'plus' %}
{% fa5_icon 'file' %} {% fa5_icon 'file' %}
</button> </button>
</a>
</div> </div>
</div> </div>
</div> </div>

View File

@ -7,12 +7,13 @@ Created on: 30.11.20
""" """
from django.urls import path from django.urls import path
from intervention.views import index_view, new_view, open_view, edit_view, remove_view from intervention.views import index_view, new_view, open_view, edit_view, remove_view, new_document_view
app_name = "intervention" app_name = "intervention"
urlpatterns = [ urlpatterns = [
path("", index_view, name="index"), path("", index_view, name="index"),
path('new/', new_view, name='new'), path('new/', new_view, name='new'),
path('<id>/document/new/', new_document_view, name='new-doc'),
path('<id>', open_view, name='open'), path('<id>', open_view, name='open'),
path('<id>/edit', edit_view, name='edit'), path('<id>/edit', edit_view, name='edit'),
path('<id>/remove', remove_view, name='remove'), path('<id>/remove', remove_view, name='remove'),

View File

@ -9,7 +9,7 @@ from intervention.models import Intervention
from intervention.tables import InterventionTable from intervention.tables import InterventionTable
from konova.contexts import BaseContext from konova.contexts import BaseContext
from konova.decorators import * from konova.decorators import *
from konova.forms import RemoveForm, SimpleGeomForm from konova.forms import RemoveForm, SimpleGeomForm, NewDocumentForm
@login_required @login_required
@ -73,6 +73,45 @@ def new_view(request: HttpRequest):
return render(request, template, context) return render(request, template, context)
@login_required
def new_document_view(request: HttpRequest, id: str):
""" Renders a form for uploading new documents
Args:
request (HttpRequest): The incoming request
id (str): The intervention's id to which the new document will be related
Returns:
"""
form = NewDocumentForm(request.POST, request.FILES, user=request.user)
template = form.template
if request.method == "POST":
if form.is_valid():
doc = form.save()
intervention = get_object_or_404(Intervention, id=id)
intervention.documents.add(doc)
messages.success(
request,
_("Document '{}' added").format(doc.title)
)
return redirect(request.META.get("HTTP_REFERER", "home"))
else:
messages.info(
request,
_("There was an error on this form.")
)
return redirect(request.META.get("HTTP_REFERER", "home"))
elif request.method == "GET":
context = {
"form": form
}
context = BaseContext(request, context).context
return render(request, template, context)
else:
raise NotImplementedError
@login_required @login_required
def open_view(request: HttpRequest, id: str): def open_view(request: HttpRequest, id: str):
""" Renders a detail view for viewing an intervention's data """ Renders a detail view for viewing an intervention's data

View File

@ -13,19 +13,24 @@ from django import forms
from django.contrib.auth.models import User from django.contrib.auth.models import User
from django.contrib.gis.forms import GeometryField, OSMWidget from django.contrib.gis.forms import GeometryField, OSMWidget
from django.contrib.gis.geos import Polygon from django.contrib.gis.geos import Polygon
from django.db import transaction
from django.utils import timezone from django.utils import timezone
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from konova.models import Document
class BaseForm(forms.Form): class BaseForm(forms.Form):
""" """
Basic form for that holds attributes needed in all other forms Basic form for that holds attributes needed in all other forms
""" """
template = None
action_url = None action_url = None
form_title = None form_title = None
cancel_redirect = None cancel_redirect = None
form_caption = None form_caption = None
instance = None # The data holding model object instance = None # The data holding model object
form_attrs = {} # Holds additional attributes, that can be used in the template
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
self.instance = kwargs.pop("instance", None) self.instance = kwargs.pop("instance", None)
@ -152,6 +157,7 @@ class RemoveModalForm(BaseModalForm):
) )
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
self.template = "modal/modal_form.html"
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
self.form_title = _("Remove") self.form_title = _("Remove")
self.form_caption = _("Are you sure?") self.form_caption = _("Are you sure?")
@ -166,16 +172,54 @@ class RemoveModalForm(BaseModalForm):
self.instance.delete() self.instance.delete()
class RemoveDocumentForm(BaseModalForm): class NewDocumentForm(BaseModalForm):
confirm = forms.BooleanField( """ Modal form for new documents
label=_("Confirm"),
"""
title = forms.CharField(
max_length=500,
)
creation_date = forms.DateField(
label=_("Created on"),
label_suffix=_(""), label_suffix=_(""),
widget=forms.CheckboxInput(), help_text=_("When has this file been created? Important for photos."),
required=True, widget=forms.DateInput(
attrs={
"type": "date",
"data-provide": "datepicker",
},
format="%d.%m.%Y"
)
)
file = forms.FileField(
label=_("File"),
label_suffix=_(""),
help_text=_("Must be smaller than 15 Mb"),
)
comment = forms.CharField(
required=False,
label=_("Comment"),
label_suffix=_(""),
help_text=_("Additional comment on this file"),
widget=forms.Textarea()
) )
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
self.instance = kwargs.get("instance", None) self.form_title = _("Add new document")
self.form_title = _("Remove document") self.form_caption = _("")
self.form_caption = _("This will remove '{}'. Are you sure?").format(self.instance.title) self.template = "modal/modal_form.html"
self.form_attrs = {
"enctype": "multipart/form-data",
}
def save(self):
with transaction.atomic():
doc = Document.objects.create(
created_by=self.user,
title=self.cleaned_data["title"],
comment=self.cleaned_data["comment"],
document=self.cleaned_data["file"],
date_of_creation=self.cleaned_data["creation_date"],
)
return doc

View File

@ -20,7 +20,7 @@ from simple_sso.sso_client.client import Client
from konova.autocompletes import OrganisationAutocomplete, NonOfficialOrganisationAutocomplete from konova.autocompletes import OrganisationAutocomplete, NonOfficialOrganisationAutocomplete
from konova.settings import SSO_SERVER, SSO_PUBLIC_KEY, SSO_PRIVATE_KEY, DEBUG from konova.settings import SSO_SERVER, SSO_PUBLIC_KEY, SSO_PRIVATE_KEY, DEBUG
from konova.views import logout_view, home_view, get_document_view, new_document_view, remove_document_view from konova.views import logout_view, home_view, get_document_view, remove_document_view
sso_client = Client(SSO_SERVER, SSO_PUBLIC_KEY, SSO_PRIVATE_KEY) sso_client = Client(SSO_SERVER, SSO_PUBLIC_KEY, SSO_PRIVATE_KEY)
urlpatterns = [ urlpatterns = [
@ -35,9 +35,8 @@ urlpatterns = [
path('user/', include("user.urls")), path('user/', include("user.urls")),
path('news/', include("news.urls")), path('news/', include("news.urls")),
# Documents # Generic documents routes
path('document/<id>', get_document_view, name="doc-open"), path('document/<id>', get_document_view, name="doc-open"),
path('document/new', new_document_view, name="doc-new"),
path('document/<id>/remove', remove_document_view, name="doc-remove"), path('document/<id>/remove', remove_document_view, name="doc-remove"),
# Autocomplete paths # Autocomplete paths

View File

@ -84,23 +84,6 @@ def get_document_view(request: HttpRequest, id: str):
return FileResponse(doc.document, as_attachment=True) return FileResponse(doc.document, as_attachment=True)
@login_required
def new_document_view(request: HttpRequest):
""" Renders a form for uploading new documents
Args:
request (HttpRequest): The incoming request
Returns:
"""
template = ""
# TODO
context = {}
context = BaseContext(request, context).context
return render(request, template, context)
@login_required @login_required
def remove_document_view(request: HttpRequest, id: str): def remove_document_view(request: HttpRequest, id: str):
""" Renders a form for uploading new documents """ Renders a form for uploading new documents
@ -119,10 +102,10 @@ def remove_document_view(request: HttpRequest, id: str):
Returns: Returns:
""" """
template = "modal/modal_form.html"
doc = get_object_or_404(Document, id=id) doc = get_object_or_404(Document, id=id)
title = doc.title title = doc.title
form = RemoveModalForm(request.POST or None, instance=doc, user=request.user) form = RemoveModalForm(request.POST or None, instance=doc, user=request.user)
template = form.template
if request.method == "POST": if request.method == "POST":
if form.is_valid(): if form.is_valid():
doc.delete() doc.delete()

View File

@ -5,7 +5,7 @@
{% endcomment %} {% endcomment %}
<form method="post" action="{{form.action_url}}"> <form method="post" action="{{form.action_url}}" {% for attr_key, attr_val in form.form_attrs.items %} {{attr_key}}="{{attr_val}}"{% endfor %}>
{% csrf_token %} {% csrf_token %}
<div class="modal-header"> <div class="modal-header">
<h5 class="modal-title">{{form.form_title}}</h5> <h5 class="modal-title">{{form.form_title}}</h5>

View File

@ -14,7 +14,7 @@
{{ form.form_caption }} {{ form.form_caption }}
</small> </small>
{% endif %} {% endif %}
<form method="post" action="{{ form.action_url }}"> <form method="post" action="{{ form.action_url }}" {% for attr_key, attr_val in form.form_attrs.items %} {{attr_key}}="{{attr_val}}"{% endfor %}>
{% csrf_token %} {% csrf_token %}
{% include 'table/generic_table_form_body.html' %} {% include 'table/generic_table_form_body.html' %}
<div class="row"> <div class="row">