Редактирование django formsets: TypeError: аргумент типа 'HTML' не повторяется - PullRequest
0 голосов
/ 23 января 2020

Я пытаюсь узнать, как работают формы. По сути, у меня есть форма «Запись» и форма «гео». Я хочу, чтобы обе формы отображались на странице и отправлялись с помощью одной кнопки. Это потому, что в зависимости от URL я всегда хочу рендерить запись, но иногда я хочу рендерить гео, а иногда гео2.

В настоящее время у меня правильно отображаются формы в представлении создания. Одна кнопка отправки, данные сохранены правильно. Моя проблема заключается в редактировании.

В моем представлении редактирования из views.py ниже, когда я передаю instance = self.object в контекст для geo_metadata, а я go в представление редактирования в браузере - форма правильно заполняется всеми существующими данные. Тем не менее, когда я пытаюсь отправить из этого вида редактирования, я получаю:

    TypeError at /projects/1/recordings/16/edit/
argument of type 'HTML' is not iterable
Request Method: POST
Request URL:    http://localhost:5000/recordings/16/edit/
Django Version: 2.2.9
Exception Type: TypeError
Exception Value:    
argument of type 'HTML' is not iterable
Exception Location: C:\Users\user\AppData\Local\Programs\Python\Python37-32\lib\site-packages\crispy_forms\bootstrap.py in <genexpr>, line 235
Python Executable:  C:\Users\user\AppData\Local\Programs\Python\Python37-32\python.exe
Python Version: 3.7.1
Python Path:    
['C:\\Development\\metadata webapp\\src',
 'C:\\Users\\user\\AppData\\Local\\Programs\\Python\\Python37-32\\python37.zip',
 'C:\\Users\\user\\AppData\\Local\\Programs\\Python\\Python37-32\\DLLs',
 'C:\\Users\\user\\AppData\\Local\\Programs\\Python\\Python37-32\\lib',
 'C:\\Users\\user\\AppData\\Local\\Programs\\Python\\Python37-32',
 'C:\\Users\\user\\AppData\\Roaming\\Python\\Python37\\site-packages',
 'C:\\Users\\user\\AppData\\Local\\Programs\\Python\\Python37-32\\lib\\site-packages']
Server time:    Wed, 22 Jan 2020 22:07:55 +0000
argument of type 'HTML' is not iterable
1   {% load crispy_forms_tags %}
2   {% load static %}
3   {% if helper %}
4   **{% crispy formset helper %}**

Примечание - если я не передам instance = self.object, тогда, когда я на странице редактирования, данные для Форма записи загружена, но данные из гео нет. В этом случае отправка форм работает правильно (независимо от того, заполняю ли я гео-форму вручную или нет). Это говорит о том, что моя проблема заключается в передаче instance = self.object в запрос get (а не в .POST).

Вот мой код.

views.py:

class EditanimalView(LoginRequiredMixin, SuccessMessageMixin, UserPassesTestMixin, UpdateView):
model = animal
form_class = animalForm
template_name = 'animals/edit_animal.html'
success_message = "animal \"%(animal_name)s\" edited"
# override get_object so we can use animal_id when we use this class in urls.py
# otherwise DetailViews expect 'pk' which defaults to the primary key of the model.

def get_object(self):
    zoo_id_ = self.kwargs.get("zoo_id")
    animal_id_ = self.kwargs.get("animal_id")
    return get_object_or_404(animal, animal_id=animal_id_, zoo=zoo_id_)

def get_context_data(self, **kwargs):
    context = super(EditanimalView, self).get_context_data(**kwargs)
    zoo_id = self.kwargs.get("zoo_id")
    animal_id = self.kwargs.get("animal_id")
    # If data is posted through the form:
    if self.request.POST:
        context['geo_metadata'] = geoMetadataFormSet(self.request.POST, instance=self.object
    # Else if the form is blank
    else:
        queryset_list = animal.objects.filter(animal_id=animal_id)
        context['geo_metadata'] = geoMetadataFormSet(instance=self.object)
    return context

def get_form(self, form_class=None):
    form = super(EditanimalView, self).get_form(form_class)
    return form

def get_success_url(self):
    return reverse('animals:add-animal', kwargs={'zoo_id':self.kwargs.get("zoo_id")})

forms.py

geoMetadataFormSet = inlineformset_factory(
    Recording, geoMetadata, form=geoMetadataForm,
    fields=[(fields)] extra=1, min_num=0, max_num=1, can_delete=True, validate_min=True
)

шаблон. html

{% load crispy_forms_tags %}
{% load static %}
{% if helper %}
{% crispy formset helper %}
{% endif %}
{{ formset.management_form|crispy }}
{% if formset.prefix == 'testfile_set' %}
<table>
    {% for form in formset.forms %}
    <tr class="{% cycle 'row1' 'row2' %} formset_row-{{ formset.prefix }}">
        {% for field in form.visible_fields %}
        <td>
            {% if forloop.first %}
            {% for hidden in form.hidden_fields %}
            {{ hidden }}
            {% endfor %}
            {% endif %}
            {{ field.errors.as_ul }}
            {{ field|as_crispy_field }}
        </td>
        {% endfor %}
    </tr>
    {% endfor %}
</table>
{% endif %}
...