title: Django modelformset_factory save nothing
body: <p>Created a set of forms for a simple model. When I am try to change the model object data in the form and save these changes in the database, the new data is not saved as a result, and a redirect to the form page with the same data occurs, although at least messages about the success or failure of the operation should be output. The terminal does not return any errors, it is written in the logs that the correct request was sent, the test server works without drops in normal mode. There is an opinion that the reason for this is a refusal to validate, but for what reason this happens and where exactly the error is hidden, it is not yet possible to understand.</p>
  
  <p>And</p>
  
  <p>When I clicked a "save" button, see this message in terminal (see below):</p>
  
  <blockquote>
    <p>[25/Aug/2017 18:03:06] "GET
    /categories/?csrfmiddlewaretoken=igSZl3z8pcF9qRGaMts9hG3T9dyaIpVvAxB672R34bmKvGYd6pymjmtwyEgDHGg2&amp;form-TOTAL_FORMS=6&amp;form-INITIAL_FORMS=5&amp;form-MIN_NUM_FORMS=0&amp;form-MAX_NUM_FORMS=1000&amp;form-0-id=1&amp;form-0-name=fhdrhddh&amp;form-0-order=0&amp;form-1-id=2&amp;form-1-name=gdegasf&amp;form-1-order=6&amp;form-2-id=3&amp;form-2-name=dfdgbsbgsdgs&amp;form-2-order=2&amp;form-3-id=4&amp;form-3-name=dbgsgbasedgbaedvg&amp;form-3-order=3&amp;form-4-id=5&amp;form-4-name=dgfsdg3waesdvz&amp;form-4-order=4&amp;form-5-id=&amp;form-5-name=&amp;form-5-order=0
    HTTP/1.1" 200 7502</p>
  </blockquote>
  
  <p>models.py (categories app)</p>
  
  <pre><code>from django.db import models
  
  # Create your models here.
  
  class Category(models.Model):
      name = models.CharField(max_length = 30, db_index = True, unique = True, verbose_name = "Title")
      order = models.PositiveSmallIntegerField(default = 0, db_index = True, verbose_name = "Serial number")
      def __str__(self):
          return self.name
      class Meta:
          ordering = ["order", "name"]
          verbose_name = "category"
          verbose_name_plural = "categories"
  </code></pre>
  
  <p>views.py (categories app)</p>
  
  <pre><code>from django.views.generic.base import TemplateView
  from django.forms.models import modelformset_factory
  from django.shortcuts import redirect
  from django.contrib import messages
  from categories.models import Category
  from generic.mixins import CategoryListMixin
  
  CategoriesFormset = modelformset_factory(Category, can_delete=True, fields = '__all__', extra=1, max_num=None)
  
  class CategoriesEdit(TemplateView, CategoryListMixin):
      template_name = "categories_edit.html"
      formset = None
      def get(self, request, *args, **kwargs):
          self.formset = CategoriesFormset()
          return super(CategoriesEdit, self).get(request, *args, **kwargs)
      def get_context_data(self, **kwargs):
          context = super(CategoriesEdit, self).get_context_data(**kwargs)
          context["formset"] = self.formset
          return context
      def post(self, request, *args, **kwargs):
          self.formset = CategoriesFormset(request.POST)
          if self.formset.is_valid():
              self.formset.save()
              messages.api.add_message(request, messages.SUCCESS, "List of categories successfully changed")
              return redirect("categories_edit")
          else:
              messages.api.add_message(request, messages.SUCCESS, "Something is wrong!!!")
              return super(CategoriesEdit, self).get(request, *args, **kwargs)
  </code></pre>
  
  <p>mixins.py</p>
  
  <pre><code>from django.views.generic.base import ContextMixin
  
  class CategoryListMixin(ContextMixin):
      def get_context_data(self, **kwargs):
          context = super(CategoryListMixin, self).get_context_data(**kwargs)
          context["current_url"] = self.request.path
          return context
  </code></pre>
  
  <p>categories_edit.html (categories app)</p>
  
  <pre><code>{% extends "categories_base.html" %}
  {% block title %} Categories {% endblock %}
  {% block main %}
      {% include "generic/messages.html" %}
      {{ formset.errors }}
      &lt;h2&gt;Categories&lt;/h2&gt;
      &lt;form action="" method="post"&gt;
          {% include "generic/formset.html" %}
          &lt;div class="submit-button"&gt;&lt;input type="submit" value="Save"&gt;&lt;/div&gt;
      &lt;/form&gt;
  {% endblock %}
  </code></pre>
  
  <p>formset.html (categories app)</p>
  
  <pre><code>{% csrf_token %}
  {{ formset.management_form }}
  &lt;table class="form"&gt;
      &lt;tr&gt;
          &lt;th&gt;&lt;/th&gt;
          {% with form=formset|first %}
              {% for field in form.visible_fields %}
                  &lt;th&gt;
                      {{ field.label }}
                      {% if field.help_text %}
                          &lt;br&gt;{{ field.help_text }}
                      {% endif %}
                  &lt;/th&gt;
              {% endfor %}
          {% endwith %}
      &lt;/tr&gt;
      {% for form in formset %}
          &lt;tr&gt;
              &lt;td&gt;
                  {% for field in form.hidden_fields %}
                      {{ field }}
                  {% endfor %}
              &lt;/td&gt;
              {% for field in form.visible_fields %}
                  &lt;td&gt;
                      {% if field.errors.count &gt; 0 %}
                          &lt;div class="error-list"&gt;
                              {{ field.errors }}
                          &lt;/div&gt;
                      {% endif %}
                      &lt;div class="control"&gt;{{ field }}&lt;/div&gt;
                  &lt;/td&gt;
              {% endfor %}
          &lt;/tr&gt;
      {% endfor %}
  &lt;/table&gt;
  </code></pre>
  
  <p>messages.html (categories app)</p>
  
  <pre><code>{% if messages %}
      &lt;div id="messages-list"&gt;
          {% for message in messages %}
              &lt;p class="{{ message.tags }}"&gt;{{ message }}&lt;/p&gt;
          {% endfor %}
      &lt;/div&gt;
  {% endif %}
  </code></pre>
  
  <p>urls.py (categories app)</p>
  
  <pre><code>from django.conf.urls import url
  from django.contrib.auth.decorators import login_required
  from categories.views import CategoriesEdit
  
  urlpatterns = [
      url(r'^$', login_required(CategoriesEdit.as_view()), name  = "categories_edit"),
  ]
  </code></pre>
  
  <p>settings.py (project)</p>
  
  <pre><code>"""
  Django settings for t****** project.
  
  Generated by 'django-admin startproject' using Django 1.10.6.
  
  For more information on this file, see
  https://docs.djangoproject.com/en/1.10/topics/settings/
  
  For the full list of settings and their values, see
  https://docs.djangoproject.com/en/1.10/ref/settings/
  """
  
  import os
  
  BASE_DIR = os.path.dirname(os.path.dirname(__file__))
  
  # Quick-start development settings - unsuitable for production
  # See https://docs.djangoproject.com/en/1.10/howto/deployment/checklist/
  
  # SECURITY WARNING: keep the secret key used in production secret!
  SECRET_KEY = '***************************************************'
  
  # SECURITY WARNING: don't run with debug turned on in production!
  DEBUG = True
  
  ALLOWED_HOSTS = []
  
  
  # Application definition
  
  INSTALLED_APPS = [
      'django.contrib.admin',
      'django.contrib.auth',
      'django.contrib.contenttypes',
      'django.contrib.sessions',
      'django.contrib.messages',
      'django.contrib.staticfiles',
      'guestbook',
      'categories',
      'imagepool',
      'page',
      'main',
      'news',
      'shop',
      'django.contrib.sites',
      'django_comments',
      'easy_thumbnails',
      'taggit',
      'precise_bbcode',
  ]
  
  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',
  ]
  
  ROOT_URLCONF = 't******.urls'
  
  TEMPLATES = [
      {
          'BACKEND': 'django.template.backends.django.DjangoTemplates',
          'DIRS': [],
          'APP_DIRS': True,
          'OPTIONS': {
              'context_processors': [
                  'django.template.context_processors.debug',
                  'django.template.context_processors.request',
                  'django.contrib.auth.context_processors.auth',
                  'django.contrib.messages.context_processors.messages',
              ],
          },
      },
  ]
  
  WSGI_APPLICATION = 'tdkennel.wsgi.application'
  
  
  # Database
  # https://docs.djangoproject.com/en/1.10/ref/settings/#databases
  
  DATABASES = {
      'default': {
          'ENGINE': 'django.db.backends.postgresql',
          'NAME': 't******l',
          'USER': 'p*******',
          'PASSWORD': '********',
          'HOST': '',
          'PORT': '5432',
      }
  }
  
  # Password validation
  # https://docs.djangoproject.com/en/1.10/ref/settings/#auth-password-validators
  
  AUTH_PASSWORD_VALIDATORS = [
      {
          'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
      },
      {
          'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
      },
      {
          'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
      },
      {
          'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
      },
  ]
  
  
  # Internationalization
  # https://docs.djangoproject.com/en/1.10/topics/i18n/
  
  LANGUAGE_CODE = 'en-us'
  
  TIME_ZONE = 'UTC'
  
  USE_I18N = True
  
  USE_L10N = True
  
  USE_TZ = True
  
  
  # Static files (CSS, JavaScript, Images)
  # https://docs.djangoproject.com/en/1.10/howto/static-files/
  
  STATIC_URL = '/static/'
  STATICFILES_DIRS = (os.path.join(BASE_DIR, 'static'),)
  
  MEDIA_ROOT = os.path.join(BASE_DIR, 'upload')
  MEDIA_URL = '/media/'
  
  LOGIN_URL = "login"
  LOGOUT_URL = "logout"
  
  SITE_ID = 1
  
  THUMBNAIL_BASEDIR = "thumbnails"
  THUMBNAIL_BASEDIR = {"goods.Good.image": {"base": {"size": (200, 100)},},}
  
  LOGIN_REDIRECT_URL = "main"
  </code></pre>