django:如何在表单向导中使用inlineformset?

发布于 2024-11-15 12:01:56 字数 3588 浏览 3 评论 0原文

我正在展示两个单独的示例项目。第一个是与联系人相关的,展示了使用表单向导的原理。第二个是与食谱相关的项目的成分,它展示了如何在表单中使用内联。我希望内联在我的表单向导中的工作方式与它们在正常表单中的工作方式相同。

我有一个表单向导多步骤表单正在工作。它基于此处的示例。我稍微改变了它以使用模型形式。

models.py

from django.db import models

# Create your models here.
class Contact(models.Model):
    subject = models.CharField(max_length=50)
    sender = models.EmailField()

    def __unicode__(self):
        return self.subject

class Contact2(models.Model):
    message = models.TextField(max_length=500)

    def __unicode__(self):
        return self.message

forms.py

class ContactForm1(forms.ModelForm):
    class Meta:
        model = Contact

class ContactForm2(forms.ModelForm):
    class Meta:
        model = Contact2

class ContactWizard(FormWizard):
    @property
    def __name__(self):
        return self.__class__.__name__

    def done(self, request, form_list):
#        do_something_with_the_form_data(form_list)
        return HttpResponseRedirect('/done/')

urls.py

(r'^contact/$', ContactWizard([ContactForm1, ContactForm2])),

另外,我将内联生成到另一个表单中。在我看来,我是通过 inlineformset_factory 来做到这一点的。 这与上面的表单向导示例无关。这是食谱示例的成分。 我这样做是这样的:

views.py

def add(request):
    IngredientFormSet = inlineformset_factory(Recipe, Ingredient, 
                fk_name="recipe", 
                formfield_callback=curry(ingredient_form_callback, None))

    if request.method == 'POST':
        form = RecipeForm(request.POST)
        formset = IngredientFormSet(request.POST)
        if form.is_valid() and formset.is_valid():
            recipe = form.save()
            formset = IngredientFormSet(request.POST, instance=recipe)            
            formset.save()
            return redirect("/edit/%s" % recipe.id)
    else:
        form = RecipeForm()
        formset = IngredientFormSet()

    return render_to_response("recipes_add.html", {"form":form, "formsets":formset}, context_instance=RequestContext(request))

recipes_add.html

<form method="post">
{% csrf_token %}
    <table>
    {{ form }}
    </table>
    <hr>
    <h3>Ingredients</h3>
    <div class="inline-group">
      <div class="tabular inline-related last-related">
          {{ formsets.management_form }}
          {% for formset in formsets.forms %}
          <table>
              {{ formset }}
          </table>
          {% endfor %}
      </div>
    </div>
    <p class="success tools"><a href="#" class="add">Add another row</a></p>
    <input type="submit" value="Add">
</form>

如何让内联在我的formwizard多步骤表单中工作? models.py 现在看起来像这样,因为我希望书籍能够内联联系。我希望内联位于表单向导的第一步。然后执行步骤 2 并完成。

from django.db import models

# Create your models here.
class Contact(models.Model):
    subject = models.CharField(max_length=50)
    sender = models.EmailField()

    def __unicode__(self):
        return self.subject

class Contact2(models.Model):
    message = models.TextField(max_length=500)

    def __unicode__(self):
        return self.message

class Book(models.Model):
   author = models.ForeignKey(Contact)
   title = models.CharField(max_length=100)

I'm displaying two separate sample projects. The first is a Contact related and shows the principle of using the formwizard. The second is an ingredients to recipes related project which shows how to use inlines within a form. I want inlines to be in my formwizard the same way they work in a normal form.

I have a formwizard multistep form working. It is based off the example here. I've changed it slightly to use modelform.

models.py

from django.db import models

# Create your models here.
class Contact(models.Model):
    subject = models.CharField(max_length=50)
    sender = models.EmailField()

    def __unicode__(self):
        return self.subject

class Contact2(models.Model):
    message = models.TextField(max_length=500)

    def __unicode__(self):
        return self.message

forms.py

class ContactForm1(forms.ModelForm):
    class Meta:
        model = Contact

class ContactForm2(forms.ModelForm):
    class Meta:
        model = Contact2

class ContactWizard(FormWizard):
    @property
    def __name__(self):
        return self.__class__.__name__

    def done(self, request, form_list):
#        do_something_with_the_form_data(form_list)
        return HttpResponseRedirect('/done/')

urls.py

(r'^contact/

Separately I have inlines being generated into another form. I'm doing this via inlineformset_factory in my view. This is not connected to the formwizard example above. This is an ingredients to recipes example.
I'm doing this like:

views.py

def add(request):
    IngredientFormSet = inlineformset_factory(Recipe, Ingredient, 
                fk_name="recipe", 
                formfield_callback=curry(ingredient_form_callback, None))

    if request.method == 'POST':
        form = RecipeForm(request.POST)
        formset = IngredientFormSet(request.POST)
        if form.is_valid() and formset.is_valid():
            recipe = form.save()
            formset = IngredientFormSet(request.POST, instance=recipe)            
            formset.save()
            return redirect("/edit/%s" % recipe.id)
    else:
        form = RecipeForm()
        formset = IngredientFormSet()

    return render_to_response("recipes_add.html", {"form":form, "formsets":formset}, context_instance=RequestContext(request))

recipes_add.html

<form method="post">
{% csrf_token %}
    <table>
    {{ form }}
    </table>
    <hr>
    <h3>Ingredients</h3>
    <div class="inline-group">
      <div class="tabular inline-related last-related">
          {{ formsets.management_form }}
          {% for formset in formsets.forms %}
          <table>
              {{ formset }}
          </table>
          {% endfor %}
      </div>
    </div>
    <p class="success tools"><a href="#" class="add">Add another row</a></p>
    <input type="submit" value="Add">
</form>

How can I get the inlines to work within my formwizard multistep form?
The models.py now looks like this because I want books to be inlines to contact. I want the inlines to be on the first step of my formwizard. Then go through to step 2 and finish.

from django.db import models

# Create your models here.
class Contact(models.Model):
    subject = models.CharField(max_length=50)
    sender = models.EmailField()

    def __unicode__(self):
        return self.subject

class Contact2(models.Model):
    message = models.TextField(max_length=500)

    def __unicode__(self):
        return self.message

class Book(models.Model):
   author = models.ForeignKey(Contact)
   title = models.CharField(max_length=100)
, ContactWizard([ContactForm1, ContactForm2])),

Separately I have inlines being generated into another form. I'm doing this via inlineformset_factory in my view. This is not connected to the formwizard example above. This is an ingredients to recipes example.
I'm doing this like:

views.py

recipes_add.html


How can I get the inlines to work within my formwizard multistep form?
The models.py now looks like this because I want books to be inlines to contact. I want the inlines to be on the first step of my formwizard. Then go through to step 2 and finish.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

旧伤慢歌 2024-11-22 12:01:56

Django(1.4 以下版本)中包含的表单向导不支持表单集。从版本 1.4 开始,将会有更好的实现(参见 https://docs.djangoproject.com/en/dev/ref/contrib/formtools/form-wizard/

回到你的问题,如果你等不及下一个 Django 版本 - 我认为 -你可以坚持使用 django-formwizard。最后一个版本 (1.0) 的 api 与即将推出的 Django formwizard 兼容。

通过新的表单向导实现,您可以像使用普通表单一样使用表单集。

The formwizard included in Django (below version 1.4) doesn't support formsets. Beginning with version 1.4, there will be a much better implementation (see https://docs.djangoproject.com/en/dev/ref/contrib/formtools/form-wizard/)

Back to your question, if you can't wait for the next Django release - which I assume - you could stick to django-formwizard. The last release (1.0) is api compatible to the upcoming Django formwizard.

With the new formwizard implementation you can use FormSets the same way you use normal Forms.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文