Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
manhattan
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
InnovacionDocente
manhattan
Commits
fa4ba0ad
Commit
fa4ba0ad
authored
Oct 30, 2020
by
Enrique Matías Sánchez (Quique)
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Elaboración de las memorias (2)
Guardar los cambios
parent
d5f287bb
Pipeline
#613
failed with stage
in 0 seconds
Changes
6
Pipelines
1
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
112 additions
and
9 deletions
+112
-9
Pipfile
Pipfile
+1
-0
Pipfile.lock
Pipfile.lock
+0
-0
0014_auto_20201030_1510.py
indo/migrations/0014_auto_20201030_1510.py
+33
-0
models.py
indo/models.py
+8
-1
views.py
indo/views.py
+48
-1
detail.html
templates/memoria/detail.html
+22
-7
No files found.
Pipfile
View file @
fa4ba0ad
...
...
@@ -23,6 +23,7 @@ python3-saml = "*"
social-auth-app-django = "*"
social-auth-core = {extras = ["saml"],version = "*"}
zeep = "*"
python-magic = "*"
[requires]
python_version = "3.7"
Pipfile.lock
View file @
fa4ba0ad
This diff is collapsed.
Click to expand it.
indo/migrations/0014_auto_20201030_1510.py
0 → 100644
View file @
fa4ba0ad
# Generated by Django 3.1.2 on 2020-10-30 14:10
import
django.core.validators
from
django.db
import
migrations
,
models
class
Migration
(
migrations
.
Migration
):
dependencies
=
[(
'indo'
,
'0013_auto_20201026_1053'
)]
operations
=
[
migrations
.
AlterModelOptions
(
name
=
'memoriasubapartado'
,
options
=
{
'ordering'
:
(
'apartado__numero'
,
'peso'
),
'verbose_name'
:
'subapartado de la memoria'
,
'verbose_name_plural'
:
'subapartados de la memoria'
,
},
),
migrations
.
AlterField
(
model_name
=
'memoriarespuesta'
,
name
=
'fichero'
,
field
=
models
.
FileField
(
blank
=
True
,
null
=
True
,
upload_to
=
'anexos_memoria/
%
Y/'
,
validators
=
[
django
.
core
.
validators
.
FileExtensionValidator
(
allowed_extensions
=
[
'pdf'
])
],
verbose_name
=
'fichero PDF'
,
),
),
]
indo/models.py
View file @
fa4ba0ad
from
django.core.validators
import
FileExtensionValidator
from
django.db
import
connection
,
models
from
django.urls
import
reverse
from
django.utils.translation
import
gettext_lazy
as
_
...
...
@@ -642,7 +643,13 @@ class MemoriaRespuesta(models.Model):
'MemoriaSubapartado'
,
on_delete
=
models
.
PROTECT
,
related_name
=
'respuestas'
)
texto
=
models
.
TextField
(
_
(
'texto'
),
blank
=
True
,
null
=
True
)
fichero
=
models
.
FileField
(
'fichero PDF'
,
upload_to
=
'anexos_memoria'
,
blank
=
True
,
null
=
True
)
fichero
=
models
.
FileField
(
'fichero PDF'
,
upload_to
=
'anexos_memoria/
%
Y/'
,
blank
=
True
,
null
=
True
,
validators
=
[
FileExtensionValidator
(
allowed_extensions
=
[
'pdf'
])],
)
class
Meta
:
ordering
=
(
'-proyecto__id'
,
'subapartado'
)
...
...
indo/views.py
View file @
fa4ba0ad
# Standard library
import
csv
import
json
import
magic
from
datetime
import
date
from
os.path
import
splitext
# Third-party
from
annoying.functions
import
get_config
,
get_object_or_None
...
...
@@ -42,6 +44,8 @@ from .models import (
Criterio
,
Evento
,
MemoriaApartado
,
MemoriaRespuesta
,
MemoriaSubapartado
,
ParticipanteProyecto
,
Plan
,
Proyecto
,
...
...
@@ -598,7 +602,7 @@ class ProyectoAnularView(LoginRequiredMixin, ChecksMixin, RedirectView):
return
self
.
es_coordinador
(
self
.
kwargs
[
'pk'
])
class
MemoriaDetailView
(
LoginRequiredMixin
,
TemplateView
):
# TODO: permisos
class
MemoriaDetailView
(
LoginRequiredMixin
,
ChecksMixin
,
TemplateView
):
"""Muestra la memoria del proyecto indicado."""
template_name
=
'memoria/detail.html'
...
...
@@ -612,6 +616,49 @@ class MemoriaDetailView(LoginRequiredMixin, TemplateView): # TODO: permisos
context
[
'dict_respuestas'
]
=
proyecto
.
get_dict_respuestas_memoria
()
return
context
def
post
(
self
,
request
,
*
args
,
**
kwargs
):
proyecto
=
get_object_or_404
(
Proyecto
,
pk
=
kwargs
[
'pk'
])
subapartados
=
MemoriaSubapartado
.
objects
.
filter
(
apartado__convocatoria_id
=
proyecto
.
convocatoria_id
)
.
all
()
dict_respuestas
=
proyecto
.
get_dict_respuestas_memoria
()
for
subapartado
in
subapartados
:
respuesta
=
dict_respuestas
.
get
(
subapartado
.
id
)
if
not
respuesta
:
respuesta
=
MemoriaRespuesta
(
proyecto_id
=
proyecto
.
id
,
subapartado_id
=
subapartado
.
id
)
if
subapartado
.
tipo
==
'texto'
:
respuesta
.
texto
=
request
.
POST
.
get
(
str
(
subapartado
.
id
))
elif
subapartado
.
tipo
==
'fichero'
:
fichero
=
request
.
FILES
.
get
(
'fichero'
)
if
fichero
:
ext
=
splitext
(
fichero
.
name
)[
1
]
.
lower
()
if
ext
!=
'.pdf'
:
raise
ValidationError
(
_
(
'El fichero debe tener extensión .pdf .'
))
filetype
=
magic
.
from_buffer
(
fichero
.
read
(
2048
),
mime
=
True
)
fichero
.
seek
(
0
)
if
'pdf'
not
in
filetype
:
# application/pdf, x-pdf, x-bzpdf, x-gzpdf
raise
ValidationError
(
_
(
'El fichero no es un PDF.'
))
# fichero.name = f'{proyecto.id}.pdf'
respuesta
.
fichero
=
fichero
respuesta
.
save
()
messages
.
success
(
request
,
_
(
f
'Se ha guardado la memoria del proyecto «{proyecto.titulo}».'
)
)
return
redirect
(
'proyecto_detail'
,
proyecto
.
id
)
def
test_func
(
self
):
# TODO: Comprobar fecha y estado
return
self
.
es_coordinador
(
self
.
kwargs
[
'pk'
])
# TODO: Permitir a los correctores?
class
MemoriaPresentarView
(
LoginRequiredMixin
,
ChecksMixin
,
RedirectView
):
"""Presenta la memoria final de proyecto.
...
...
templates/memoria/detail.html
View file @
fa4ba0ad
...
...
@@ -18,7 +18,16 @@
{% trans 'Pulse el botón «
<strong>
Guardar
</strong>
» para almacenar sus cambios.' %}
{% trans 'Puede editar su memoria tantas veces como desee.' %}
<br
/>
{% trans 'Cuando esté satisfecho, pulse el botón «
<strong>
Presentar
</strong>
».' %}
{% trans 'Una vez haya presentado la memoria, ya no podrá modificarla.' %}
{% trans 'Una vez haya presentado la memoria para su corrección, ya no podrá modificarla.' %}
<br
/><br
/>
{% blocktrans with fecha=proyecto.convocatoria.fecha_max_memorias %}
Recuerde que la fecha límite para la presentación de memorias es el {{ fecha }}.
{% endblocktrans %}
<br
/>
<strong>
{% trans 'No se admitirá ninguna memoria fuera de plazo.' %}
</strong>
<!--
<strong>{% trans '¡No espere hasta el último momento para presentar la memoria!' %}</strong><br />
{% blocktrans %}En caso de que el corrector rechace la memoria, podrá subsanar sus defectos
<strong>sólo</strong> mientras esté dentro del plazo de presentación.{% endblocktrans %}
-->
</div>
<br
/>
...
...
@@ -140,23 +149,29 @@
</div>
<br
/>
<form
action=
""
method=
"post"
>
<form
action=
""
enctype=
"multipart/form-data"
method=
"post"
>
{% csrf_token %}
{% for apartado in apartados %}
<h3>
{{ apartado.numero }}. {{ apartado.descripcion }}
</h3>
{% for subapartado in apartado.subapartados.all %}
<p><strong>
{{ subapartado.descripcion }}
</strong></p>
<p
class=
"noprint"
style=
"color: gray;"
>
{{ subapartado.ayuda }}
</p>
{% with respuesta=dict_respuestas|get_item:subapartado.id %}
{% if subapartado.tipo == 'texto' %}
<textarea
class=
"textarea form-control"
name=
"{{ subapartado.id }}"
placeholder=
"{% trans 'Introduzca sus comentarios.' %}"
rows=
"10"
cols=
"80"
>
{% if respuesta %}{{ respuesta.texto }}{% endif %}
</textarea>
{% elif subapartado.tipo == 'fichero' %}
TODO: Enviar PDF
{% if respuesta.fichero %}
<p><a
href=
"{{ respuesta.fichero.url }}"
>
{% trans 'PDF actual' %}
</a></p>
{% endif %}
<input
type=
"file"
name=
"fichero"
accept=
".pdf"
>
{% endif %}
{% endwith %}
<br
/>
{% endfor %}
{% endfor %}
...
...
@@ -164,18 +179,18 @@
<!-- Botones -->
<br
style=
"clear: both;"
/>
<div
class=
"btn-group noprint"
role=
"group"
aria-label=
"Botones"
>
<a
href=
"{% url 'proyecto_detail' proyecto.id %}"
class=
"btn btn-
info
"
title=
"{% trans 'Cancelar' %}"
>
<a
href=
"{% url 'proyecto_detail' proyecto.id %}"
class=
"btn btn-
warning
"
title=
"{% trans 'Cancelar
- Se perderán los cambios no guardados
' %}"
>
<span
class=
"fas fa-times"
></span>
{% trans 'Cancelar' %}
</a>
{# TODO if permitir_edicion #}
<button
class=
"btn btn-success"
type=
"
button
"
>
<button
class=
"btn btn-success"
type=
"
submit"
title=
"{% trans 'Guardar cambios' %}
"
>
<span
class=
"far fa-save"
></span>
{% trans 'Guardar' %}
</button>
{# endif #}
{# TODO if es_coordinador #}
<button
class=
"btn btn-
warning
"
data-toggle=
"modal"
data-target=
"#presentarModal"
<button
class=
"btn btn-
danger
"
data-toggle=
"modal"
data-target=
"#presentarModal"
type=
"button"
>
<span
class=
"fas fa-file-export"
></span>
{% trans 'Presentar' %}
</button>
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment