Django modelformsets не содержит POST-данных
У меня есть следующая модель
models.py
class Activity(Model):
user = ForeignKey(settings.AUTH_USER_MODEL, on_delete=CASCADE)
activity = CharField(max_length=100, default='')
number = IntegerField(default=1)
и следующая модельная форма
forms.py
class ActivityForm(ModelForm):
class Meta:
model = Activity
fields = ['activity']
Сделано в виде modelformset в представлении
views.py
activities = Activity.objects.filter(user=request.user)
ActivityFormSet = modelformset_factory(Activity, form=ActivityForm)
formset = ActivityFormSet(queryset=activities)
if request.method == 'POST':
if 'save' in request.POST:
formset = ActivityFormSet(request.POST)
if formset.is_valid():
Мой взгляд останавливается на этом. Потому что набор форм не действителен, и formset.errors выдает мне:
[{'activity': ['This field is required.'], 'id': ['This field is required.']}, {}]
из моего шаблона:
<form enctype="multipart/form-data" method = "POST">
{% csrf_token %}
{{ form2.management_form }}
{% for hidden in form2.hidden_fields %}
{{ hidden }}
{% endfor %}
{% for activity in activities %}
<div class="expandable-input-small" id="input_activity{{ activity.number }}" contenteditable="true"></div>
<div id="form_activity{{ activity.number }}">{% for hidden in formset.form.hidden_fields %}{{ hidden }}{% endfor %}{{ formset.form.activity.as_hidden }}</div>
{% endfor %}
<button name="save" class="btn btn-primary" type = "submit" value = "Click" onclick="get_data()">Save</button>
</form>
Я использую javascript для передачи данных из contenteditable в скрытое поле формы перед отправкой с помощью функции get_data(). Я протестировал и подтвердил, что эта функция работает, вызвав ее вне формы и установив поля ввода как не скрытые.
Неважно, что я делаю - даже если я скрываю поля и ввожу данные вручную, набор форм не содержит никаких данных о посте. Я пытался использовать документацию, чтобы понять это - но большинство примеров (по какой-то причине) взяты из консольных команд, в отличие от отображения набора форм в шаблоне.
Что я делаю неправильно? Как мне это исправить?
С этой строкой
{% for activity in activities %}
вы перебираете действия. Однако вы не перебираете формы в наборе форм. так,
{{ formset.form.activity.as_hidden }}
Каждый раз создается одно и то же поле, что приводит к отсутствию полей в POST
Попробуйте заменить
{{ formset.form.activity.as_hidden }}
с чем-то вроде
{% for form in formset %}
{% if forloop.counter == forloop.parentloop.counter %}
{{ form.activity.as_hidden }}
{{ form.id.as_hidden}}
{%endif%}
{% endfor %}
Что должно дать вам необходимые поля для каждой активности (соответствие цикла formset через count с циклом activities). Обычно в формах с набором форм скрытый ID предоставляется автоматически, но здесь, надеюсь, явное создание его как_hidden сделает свое дело.