Метод Clean() из пользовательской формы Django не вызывается

Мне нужно проверить условие в моем экспериментальном классе, которое зависит от нескольких полей. Я указал "чистый" метод в своем ExperimentForm, но метод проверки никогда не вызывается. Ошибки проверки модели отлично отображаются.

Вот как выглядит файл forms.py:

from django import forms
from django.utils.translation import ugettext, ugettext_lazy as _

class ExperimentForm(forms.Form):
    name = forms.CharField(max_length=254)
    student_n = forms.IntegerField()
    expert_n = forms.IntegerField()
    student_cmd_n = forms.IntegerField()
    expert_cmd_n = forms.IntegerField()
    is_active = forms.BooleanField()

    error_messages = {
        'insufficient_assignments': _("The total number of commands to be evaluated must be"
                  "Greater than 28. Right now it's  %(command_number)"),
    }

    def clean(self):
        cleaned_data = super(ExperimentForm, self).clean()
        s_n = cleaned_data.get("student_n")
        e_n = cleaned_data.get("expert_n")
        s_cmd_n = cleaned_data.get("student_cmd_n")
        e_cmd_n = cleaned_data.get("expert_cmd_n")
        command_number = s_n*s_cmd_n + e_n*e_cmd_n

        if command_number < 28:
            raise forms.ValidationError(
                self.error_messages['insufficient_assignments'],
                code='insufficient_assignments',
                params={'command_number': command_number},
            )
        return self.cleaned_data

Это мои views.py

from __future__ import unicode_literals
from django.shortcuts import render
from django.http import HttpResponse
from django.template import loader
from django.core.urlresolvers import reverse_lazy
from vacs.forms import ExperimentForm
from django.views.generic import TemplateView,ListView
from django.views.generic.edit import FormView, CreateView, UpdateView, DeleteView
from django.views.generic.detail import DetailView
from vacs.models import Experiment

class ExperimentView(FormView):
    template_name = 'vacs/experiment.html'
    form_class = ExperimentForm
    success_url = '/vacs/experiments/'

    def form_valid(self, form):
        return super(ExperimentView, self).form_valid(form)

class ExperimentDetailView(DetailView):
    model = Experiment

class ExperimentListView(ListView):
    model = Experiment

class ExperimentCreateView(CreateView):
    model = Experiment
    success_url = reverse_lazy('experiment_list')
    fields = ['name', 'student_n', 'expert_n', 'student_cmd_n', 'expert_cmd_n']

class ExperimentUpdateView(UpdateView):
    model = Experiment
    success_url = reverse_lazy('experiment_list')
    fields = ['is_active' ]

class ExperimentDeleteView(DeleteView):
    model = Experiment
    success_url = reverse_lazy('experiment_list')

Models.py определяется следующим образом:

# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models
from django.core.validators import MaxValueValidator, MinValueValidator
from django.utils.encoding import python_2_unicode_compatible
from django.contrib.auth.models import User
from django.db import models
from jsonfield import JSONField
import collections

class Experiment(models.Model):
    name = models.CharField(max_length=200)
    student_n = models.IntegerField(default=0,
            validators=[MinValueValidator(0)])
    expert_n = models.IntegerField(default=0,
            validators=[MinValueValidator(0)])
    student_cmd_n  = models.IntegerField(default=2,
            validators=[MinValueValidator(2)])
    expert_cmd_n  = models.IntegerField(default=1,
            validators=[MinValueValidator(1)])
    is_active = models.BooleanField(default=True)
    replications = JSONField(load_kwargs={'object_pairs_hook': collections.OrderedDict},
            blank=True)

Наконец, шаблон эксперимент_форма.html:

{% extends "vacs/base.html" %}
{% load widget_tweaks %}
{% block content %}

{% if form.errors %}
<div class="alert alert-danger" role="alert">
    Form error!
</div>
{% endif %}

<form method="post">{% csrf_token %}
    {{ form.as_p }}
    <input type="submit" value="Submit" />
</form>

{% endblock %}

Спасибо!

1 ответ

Вы должны переопределить save метод для модели.

Так бегать clean_fields() а также clean() Добавьте следующий метод к вашей модели

def save(self, *args, **kwargs):
    self.full_clean()
    return super().save(*args, **kwargs)

Во время обработки формы используются три метода очистки. Обычно они выполняются, когда вы вызываете is_valid() метод на форме.

Документация Django

Другие вопросы по тегам