【问题标题】:multiple forms in one step, Django Wizard form多表单一步,Django Wizard表单
【发布时间】:2022-01-03 09:26:21
【问题描述】:

我正在尝试在 Step 中创建 2 个模型表单,其中一个是 Modelformset,以前有人这样做过吗,这将非常有帮助。 我在我的项目中使用 Django 2。 谢谢。

class Post(models.Model):
    main_image = models.ImageField('main_image', upload_to='main_images/', blank=True, null=True)

    def __str__(self):
        return str(self.pk)


class PostImages(models.Model):
    image = models.ImageField('Foto', upload_to='post_images/', blank=True, null=True)
    post = models.ForeignKey(Post,related_name='myposts',on_delete=models.CASCADE, null=True)
    def __str__(self):
        return str(self.pk)

我的 Forms.py

我在这里尝试创建两个表单,第一个是main_image,另一个是一步一步的formsetfield。这可行,但我无法获取我的表单集的实例,所以我无法保存它。

class step3Form(forms.ModelForm):
    main_image = forms.FileField(widget=forms.FileInput(attrs={'class': 'custom-control'}), required=True, label=_('Hauptbild:'))
    formsetfield = modelformset_factory(PostImages, ImageForm, can_delete=True)
    class Meta:
        model = Post
        fields = ('main_image',)
    def __init__(self, *args, **kwargs):
        super(step3Form, self).__init__(*args, **kwargs)

views.py

我在这里做什么来获取我的 Formset 的实例?为了拯救它!

class PostCreateView(LoginRequiredMixin, SessionWizardView):
    instance = None
    form_list = [PostForm, PostFormSecondStep, step3Form, step4Form]
    file_storage = FileSystemStorage(location=os.path.join(settings.MEDIA_ROOT, 'media'))

    def get_template_names(self):
        return [TEMPLATES[self.steps.current]]

    def get_form_instance(self, step):
        if self.instance is None:
            self.instance = Post()
        return self.instance

    def done(self, form_list, form_dict, **kwargs):
        form_data_dict = self.get_all_cleaned_data()
        result = {}
        self.instance.author = self.request.user.profile
        form_list[2].save()
        self.instance.save()
        form_data =  [form.cleaned_data for form in form_list]
        return redirect('post_app:post_create_page')

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        return context

html

          <form method="post" id="msform" enctype="multipart/form-data">
            {% csrf_token %}
            {{ wizard.management_form }}
            {% if wizard.form.forms %}
            {% for form in wizard.form.forms %}
                          {{ form }}
                          {% endfor %}
                {% else %}
                {% if wizard.form.non_field_errors %}
                    <ul>
                      {% for error in wizard.form.non_field_errors %}
                      <li>{{ error }}</li>
                      {% endfor %}
                    </ul>
                    {% endif %}
                    {{ wizard.form.main_image.label_tag }}
                    {{ wizard.form.main_image }}
                    {{ wizard.form.main_image.errors }}
                    {{ wizard.form.formsetfield.errors }}
                <div id="formset" data-formset-prefix="{{ wizard.form.formsetfield.prefix }}">
                  {{ wizard.form.formsetfield.management_form }}
                  <div data-formset-body>
                    {% for form in wizard.form.formsetfield %}
                    {{ form.non_field_errors }}
                      {{ form.errors }}
                    <div data-formset-form>
                      {{ form }}
                      <span class="p-2"><a class="cursor-pointer" data-formset-delete-button><i class="far fa-trash-alt"></i></a></span>
                    </div>
                    {% endfor %}
                  </div>
                  
                  <input type="button" class="btn btn-outline-dark" value="Hinzufügen" data-formset-add>
                </div>
            {% endif %}
            <button type="submit" id="submit_btn" class="action-button" name="button">Weiter</button>
            {% if wizard.steps.prev %}
            <button name="wizard_goto_step" class="action-button" type="submit" value="{{ wizard.steps.first }}">Erster Schritt</button>
            <button name="wizard_goto_step" id="back_btn" class="action-button" type="submit" value="{{ wizard.steps.prev }}">Zurück</button>
            {% endif %}
          </form>

【问题讨论】:

  • 嗨 @Abdull 欢迎来到 * 社区。如果您能提供代码的上下文,这样我们就可以确切地知道您面临的问题是什么?
  • 嗨@UmarHayat 谢谢你的评论,我添加了我的代码

标签: django django-formwizard django-2.2 multiple-forms


【解决方案1】:

在基于函数的情况下试试这个:

Forms.py

  class step3Form(forms.ModelForm):
        class Meta:
            model = Post
            fields = ('main_image',)

view.py

from django.forms import modelformset_factory

def create(request):
    formset = modelformset_factory(
                    Post,
                    form=step3Form,
                    fields=('main_image'),
                    extra=1,
                    can_delete=True
                )
    if request.method == 'POST':
       form = formset(request.POST, prefix='post')
       if form.is_valid()
          post = form.save(commit=False)
          for row in post:
              row.userID = request.user
              row.save()
          form.save()
    context['form']=formset(queryset=Post.objects.none(), prefix='post')
    return render(request, 'post/form.html',context=context)

【讨论】: