Value from session doesn't get saved to database

Hi,

I’m trying to pass values from one view to another and to save it to the database later, all this using sessions. I’m doing it with categorie and identifiant. identifiant gets properly saved but categorie doesn’t. I suspect that it comes from a bad handling at models.py level but I can’t figure out what’s wrong.

Here are my views:

class AccueilView(FormView):
    model = Consentement
    form_class = AccueilForm
    template_name = 'form1/accueil.html'
    success_url = '/entree/'

    def form_valid(self, form):
        qcon01_consent = form.cleaned_data['qcon01_consent']
        identifiant = str(uuid.uuid4())
        self.request.session['identifiant'] = identifiant
        consent = Consentement(identifiant=identifiant,
                               qcon01_consent=qcon01_consent)
        consent.save()
        return super().form_valid(form)


class EntreeView(FormView):
    model = CategorieChoice
    form_class = EntreeForm
    template_name = 'form1/entree.html'

    def form_valid(self, form):
        categorie = form.cleaned_data['categorie']
        self.request.session['categorie'] = categorie
        if categorie and 'sympathisantE' in categorie:
            return redirect('sympathisant')
        elif categorie and 'ex-adhérentE' in categorie:
            return redirect('ancien')
        else:
            return redirect('adherent')


def adherent_view(request,):
    categorie = request.session.get('categorie')
    identifiant = request.session.get('identifiant')
    success_message = None

    repondant = None
    if identifiant:
        try:
            repondant = RepondantOptionnel.objects.get(identifiant=identifiant)
        except RepondantOptionnel.DoesNotExist:
            pass

    if request.method == 'POST':
        if 'envoyer' in request.POST:
            form = AdherentForm(request.POST)
            if form.is_valid():
                form.instance.categorie = categorie
                form.instance.identifiant = identifiant
                form.save()
                return redirect('conclusion')
        elif 'enregistrer' in request.POST:
            form = AdherentOptForm(request.POST, instance=repondant)
            form.instance.categorie = categorie
            form.instance.identifiant = identifiant
            form.save()
            success_message = f"Success message!"
            messages.success(request, success_message)
            return redirect('adherent')
    else:
        form = AdherentOptForm(instance=repondant)

    context = {'form': form, 'success_message': success_message}
    return render(request, 'form1/adherent.html', context)

Here’s models.py:

class CategorieChoice(models.Model):

    class Categorie(models.TextChoices):
        ADHERENT = 'UnE adhérentE ou coopérateurICE d\'EELV', _('UnE adhérentE ou coopérateurICE d\'EELV')
        ANCIEN = 'UnE ex-adhérentE ou ex-coopérateurICE d\'EELV', _('UnE ex-adhérentE ou ex-coopérateurICE d\'EELV')
        SYMP = 'UnE sympathisantE d\'EELV et/ou du futur mouvement "Les Écologistes"', _('UnE sympathisantE d\'EELV et/ou du futur mouvement "Les Écologistes"')
    categorie = models.CharField(
        _('Êtes-vous : *'),
        choices=Categorie.choices,
        blank=False,
        default=False
        )


class RepondantOptionnel(models.Model):
    created_at = models.DateTimeField(
        auto_now_add=True
        )
    updated_at = models.DateTimeField(
        auto_now=True
        )
    identifiant = models.UUIDField(
        unique=True,
        )
    categorie = models.CharField(
        max_length=200,
        blank=True
        )

settings.py:

INSTALLED_APPS = [
    # 'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'form1',
    'django.forms',
    'django_countries',
    'django_select2',
]

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
    "django.middleware.locale.LocaleMiddleware",
    "django.middleware.common.CommonMiddleware",
]

The issue is when I send a POST request with enregistrer.

form.instance.categorie = categorie should bound the value of categorie to the form, as form.instance.identifiant = identifiant does, but categorie is not recorded in the database (and identifiant IS saved to the database).

If I add a print(categorie) statement right before return redirect('adherent'), it outputs the expected value.

I’m scratching my head at this one!

Notice how in the if section you check if form.is_valid but you don’t do that in the elif section.

As a result, I don’t think the form is being validated before the save - in which case it’s being validated at the save step - and if it’s not valid, it’s still going to issue the success message and redirect but without the data being saved.

See Validation on a ModelForm