Я никогда не пробовал то, что вы делаете здесь с ModelForm, но вы могли бы использовать оператор **, чтобы расширить ваш словарь cleaned_data в аргументы ключевого слова, ожидаемые для вашего конструктора регистрации:
registration = Registration (**cleaned_data)
Конструктор классов вашей модели принимает аргументы ключевых слов, которые метакласс Django преобразует в атрибуты уровня экземпляра полученного объекта. Оператор ** - это соглашение о вызовах, которое указывает Python расширить ваш словарь на эти ключевые аргументы.
Другими словами ...
То, что вы делаете в настоящее время, равносильно этому:
registration = Registration ({'key':'value', ...})
Это не то, что вам нужно, потому что конструктор ожидает аргументы ключевого слова, а не словарь, содержащий аргументы вашего ключевого слова.
То, что вы хотите сделать, это
registration = Registration (key='value', ...)
Что аналогично этому:
registration = Registration (**{'key':'value', ...})
Опять же, я никогда не пробовал этого, но похоже, что это будет работать, если вы не делаете ничего необычного с вашей формой, например, добавляете в нее новые атрибуты, которые не ожидаются вашим конструктором Registration. В этом случае вам, вероятно, придется изменить элементы в словаре cleaned_data, прежде чем делать это.
Похоже, что вы теряете некоторые функции, присущие ModelForms, хотя и проходите через утилиту предварительного просмотра форм. Возможно, вам следует перенести ваш вариант использования в список рассылки Django и посмотреть, есть ли потенциальное усовершенствование этого API, которое могло бы улучшить его работу с ModelForms.
Редактировать
Если не считать того, что я описал выше, вы всегда можете просто извлечь поля из словаря cleaned_data «вручную» и передать их в конструктор регистрации, но с оговоркой, которую вы должны помнить, чтобы обновить этот код как Вы добавляете новые поля в вашу модель.
registration = Registration (
x=cleaned_data['x'],
y=cleaned_data['y'],
z=cleaned_data['z'],
...
)