Skip to content
Snippets Groups Projects
Commit 70bb2a1a authored by florimondmanca's avatar florimondmanca
Browse files

fix bugs in participation and dynamic forms api

parent f4bdaf6d
Branches
No related tags found
No related merge requests found
# Generated by Django 2.0.6 on 2018-06-16 16:12
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('dynamicforms', '0013_auto_20180616_0149'),
]
operations = [
migrations.AlterField(
model_name='answer',
name='entry',
field=models.ForeignKey(help_text='Entrée associée à la réponse.', null=True, on_delete=django.db.models.deletion.CASCADE, related_name='answers', to='dynamicforms.FormEntry', verbose_name='entrée'),
),
migrations.AlterField(
model_name='question',
name='type',
field=models.CharField(choices=[('text-small', 'Texte court'), ('text-long', 'Texte long'), ('yes-no', 'Oui/Non'), ('date', 'Date'), ('sex', 'Sexe')], max_length=100, verbose_name='type de question'),
),
]
......@@ -141,6 +141,7 @@ class Answer(models.Model):
entry = models.ForeignKey(
'FormEntry',
on_delete=models.CASCADE,
null=True,
related_name='answers',
verbose_name='entrée',
help_text="Entrée associée à la réponse.")
......
"""Dynamic forms serializers."""
from typing import List
from rest_framework import serializers
from .models import Form, Section, Question, Answer, FormEntry, File
......@@ -74,6 +75,21 @@ class FormEntrySerializer(serializers.ModelSerializer):
)
answers = AnswerSerializer(many=True)
def create(self, validated_data: dict) -> FormEntry:
"""Create a form entry for validated input data."""
form = validated_data['form']
answers: List[dict] = validated_data['answers']
answer_serializer = AnswerSerializer()
form_entry = FormEntry.objects.create(form=form)
# Assign the newly created entry to each answer
for answer_data in answers:
answer = answer_serializer.create(answer_data)
form_entry.answers.add(answer)
return form_entry
class Meta: # noqa
model = FormEntry
fields = ('id', 'form', 'submitted', 'answers',)
......@@ -85,4 +85,5 @@ class ParticipationAdmin(admin.ModelAdmin):
list_display = ('user', 'edition', 'submitted', 'state')
list_filter = ('edition', 'submitted', 'state',)
readonly_fields = ('submitted',)
search_fields = ('user__first_name', 'user__last_name', 'user__email',)
# Generated by Django 2.0.6 on 2018-06-16 16:12
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('dynamicforms', '0014_auto_20180616_1812'),
('projects', '0006_auto_20180616_0145'),
]
operations = [
migrations.AddField(
model_name='participation',
name='entry',
field=models.OneToOneField(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='project_participation', to='dynamicforms.FormEntry'),
),
migrations.AlterField(
model_name='editionform',
name='edition',
field=models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='edition_form', to='projects.Edition', verbose_name='édition'),
),
migrations.AlterField(
model_name='editionform',
name='form',
field=models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='dynamicforms.Form', verbose_name="formulaire d'inscription"),
),
]
# Generated by Django 2.0.6 on 2018-06-16 17:19
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('projects', '0007_auto_20180616_1812'),
]
operations = [
migrations.AlterField(
model_name='participation',
name='entry',
field=models.OneToOneField(help_text="Réponses au formulaire d'inscription", null=True, on_delete=django.db.models.deletion.CASCADE, related_name='project_participation', to='dynamicforms.FormEntry', verbose_name='entrée'),
),
]
......@@ -180,7 +180,14 @@ class Participation(models.Model):
auto_now_add=True, verbose_name='soumis le',
help_text='Date de soumission de la participation')
# TODO link to the edition form? to a form entry?
entry = models.OneToOneField(
'dynamicforms.FormEntry',
on_delete=models.CASCADE,
null=True,
related_name='project_participation',
verbose_name='entrée',
help_text="Réponses au formulaire d'inscription",
)
STATE_PENDING = 'pending'
STATE_VALIDATED = 'valid'
......
"""Projects serializers."""
from django.db import transaction
from rest_framework import serializers
from core.fields import MarkdownField
from users.fields import UserField
from users.serializers import UserSerializer
from profiles.serializers import TutorSerializer
from dynamicforms.serializers import FormDetailSerializer
from dynamicforms.serializers import FormDetailSerializer, FormEntrySerializer
from .models import Edition, Participation, Project, EditionForm
......@@ -36,9 +37,26 @@ class ParticipationSerializer(serializers.ModelSerializer):
label='Édition',
help_text='Identifier for the associated edition.')
entry = FormEntrySerializer(write_only=True)
def create(self, validated_data: dict) -> Participation:
"""Explicitly create as entry is a nested serializer."""
with transaction.atomic():
entry_data = validated_data['entry']
entry = FormEntrySerializer().create(entry_data)
participation = Participation.objects.create(
user=validated_data['user'],
edition=validated_data['edition'],
state=Participation.STATE_PENDING,
entry=entry,
)
return participation
class Meta: # noqa
model = Participation
fields = ('id', 'submitted', 'user', 'edition', 'state',)
fields = ('id', 'submitted', 'user', 'edition', 'state', 'entry',)
extra_kwargs = {
'state': {
'label': 'State of the participation.'
......
......@@ -46,8 +46,25 @@ class ProjectViewSet(viewsets.ReadOnlyModelViewSet):
"id": 1,
"url": "http://localhost:8000/api/projects/1/",
"name": "Oser la Prépa",
"description": "Oser la Prépa est un stage d'acclimatation aux Classes Préparatoires de deux semaines qui se déroule chaque été.",
"logo": null
"description": "Oser la Prépa est un stage d'acclimatation…",
"logo": null,
"editions": [
{
"id": 1,
"url": "http://localhost:8000/api/editions/1/",
"name": "",
"year": 2018,
"project": 1,
"description": "",
"organizers": 0,
"participations": 2,
"edition_form": {
"id": 1,
"edition": 1,
"deadline": "2018-06-30"
}
}
]
}
"""
......@@ -82,16 +99,15 @@ class EditionViewSet(viewsets.ReadOnlyModelViewSet):
"url": "http://localhost:8000/api/editions/1/",
"name": "",
"year": 2018,
"project": {
"id": 1,
"url": "http://localhost:8000/api/projects/1/",
"name": "Oser la Prépa",
"description": "Oser la Prépa est un stage…",
"logo": null
},
"project": 1,
"description": "",
"organizers": 0,
"participations": 1
"participations": 2,
"edition_form": {
"id": 1,
"edition": 1,
"deadline": "2018-06-30"
}
}
]
......@@ -99,27 +115,74 @@ class EditionViewSet(viewsets.ReadOnlyModelViewSet):
Retrieve a specific edition.
Each `participation` in `participations` has the following format:
{
"id": 3,
"submitted": "2018-06-07T00:31:37.947085+02:00",
"user": {
"id": 3,
"email": "john.doe@example.com",
"profile_type": null,
"first_name": "John",
"last_name": "Doe",
"gender": null,
"phone_number": "+33 6 12 34 56 78",
"date_of_birth": null,
"url": "http://localhost:8000/api/users/3/"
},
"edition": 1,
"state": "valid"
}
### Example response
[
{
"id": 1,
"url": "http://localhost:8000/api/editions/1/",
"name": "",
"year": 2018,
"project": {
"id": 1,
"url": "http://localhost:8000/api/projects/1/",
"name": "Oser la Prépa",
"description": "Oser la Prépa est un stage…",
"logo": null
},
"project": 1,
"description": "",
"organizers": [],
"participations": [
"participations": [],
"edition_form": {
"id": 1,
"edition": 1,
"deadline": "2018-06-30",
"form": {
"id": 2,
"url": "http://localhost:8000/api/forms/2/",
"slug": "inscriptions-a-oser-la-prepa-2018",
"title": "Inscription à Oser la Prépa 2018",
"entries_count": 1,
"sections": [
{
"id": 3,
"submitted": "2018-06-07T00:31:37.947085+02:00",
"id": 1,
"title": "Enfant",
"form": 2,
"questions": [
{
"id": 14,
"type": "text-small",
"text": "Nom",
"help_text": "",
"required": true,
"section": 1
},
]
}
],
"files": [
{
"id": 1,
"name": "Autorisation parentale",
"file": "http://localhost:8000/file.pdf",
"form": 2
}
]
},
"recipient": {
"user": {
"id": 3,
"email": "john.doe@example.com",
......@@ -131,10 +194,24 @@ class EditionViewSet(viewsets.ReadOnlyModelViewSet):
"date_of_birth": null,
"url": "http://localhost:8000/api/users/3/"
},
"edition": 1,
"state": "valid"
"address": {
"line1": "Rue de Rivoli",
"line2": "",
"post_code": "75001",
"city": "Paris",
"country": {
"code": "FR",
"name": "France"
}
},
]
"promotion": 2020,
"tutoring_groups": [
1
],
"url": "http://localhost:8000/api/tutors/1/"
}
}
}
"""
queryset = Edition.objects.all()
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment