【问题标题】:django display ManyToManyField as a form fielddjango 将 ManyToManyField 显示为表单字段
【发布时间】:2013-07-28 05:48:00
【问题描述】:

我正在尝试在我的模板中显示 ManyToManyField:

class GvtCompo(models.Model):
    startDate=models.DateField(max_length=10, blank=False, null=False)
    endDate=models.DateField(max_length=10, blank=False, null=False)
    gvtCompo= models.CharField(max_length=1000, blank=False, null=False)

class Act(models.Model):
    gvtCompo= models.ManyToManyField(GvtCompo)

在我看来,我可以显示对象,没问题:

for gvtCompo in act.gvtCompo.all():
    print gvtCompo.gvtCompo

在我的模板中,我有一个带有此代码的“GvtCompo 对象”列表(不好):

{% for field in form %}
    <div class="fieldWrapper">
        {{ field.errors }}
        {{ field }}
    </div>
{% endfor %}

我试图让它更好,但下面的代码不起作用(没有出现):

{% for field in form %}
    {% if field.name == "gvtCompo" %}
        {% for gvtCompo in field.gvtCompo.all %}
            {{ gvtCompo.gvtCompo }}
        {% endfor %}
    {% endif %}
{% endfor %}

怎么了?

*编辑:*

如果我不使用表单而是传递给 render_to_response 的模型(行为)实例,它会显示 ManyToManyField 值

{% for gvtCompo in field.gvtCompo.all %}

改为

{% for gvtCompo in act.gvtCompo.all %}

但是表单域已经没有了,所以不能修改、验证和保存!

【问题讨论】:

  • 试试这个 - {% for x,y in form.fields.gvtCompo.choices %}{% endfor %}
  • 它给了我表格下我表中所有记录的列表:1,GvtCompo 对象,2,GvtCompo 对象...
  • 您可以在模板中将其用作 {{ x }}{{ y }} value-name of value
  • 问题是我想显示链接到我的实例的记录,而不是所有记录。

标签: django templates manytomanyfield


【解决方案1】:

您正在跳过一个步骤。您首先需要创建一个表单。

在 forms.py 中,您可以创建一个 ModelForm。 ModelForm 是基于您的模型的表单:

从 django.forms 导入 ModelForm from myapp.models 导入法

class ActForm(ModelForm):
   class Meta:
       model = Act

那么你的看法:

from myapp.models import Act
from myapp.forms import ActForm


def add_view(request):
    if request.method == 'POST':
        form = ArticleForm(request.POST)
        if form.is_valid():
            form.save()
    else:
        form = ActForm() # Creating a empty form.
    return render_to_response("template.html", {
        "form": form,
    })

def edit_view(request):
    obj = Act.objects.get(pk=1)

    if request.method == 'POST':
        form = ArticleForm(request.POST)
        if form.is_valid():
            form.save()
    else:
        form = ActForm(instance=obj) # Creating form pre-filled with obj.
    return render_to_response("template.html", {
        "form": form,
    })

如果您想多次实施这种情况。干:https://docs.djangoproject.com/en/1.5/topics/class-based-views/intro/#handling-forms-with-class-based-views

在你的 template.html 中:

{{ form }}

免责声明:此代码未经测试。 https://docs.djangoproject.com/en/1.5/ref/forms/ https://docs.djangoproject.com/en/1.5/topics/forms/modelforms/

更新:

您可以将多个表单传递给模板中的一个&lt;form&gt;...&lt;/form&gt;。所以创建两个表格。一份法案表格(见上文)和一份 GvtCompo 表格集。 formset 包含所有与 Act 相关的 GvtCompo。

from django.forms.models import modelformset_factory

act = Act.objects.get(pk=1) #The same act as you used to create the form above.

GvtFormSet = modelformset_factory(GvtCompo)
formset = GvtFormSet(queryset=act.gvtCompo.all())

模板可以是:

<form ...>
{% for field in form %}
    {% if field.name == "gvtCompo" %}
        {{ formset }}
    {% else %}
        {{ field }}
    {% endif %}
{% endfor %}
</form>

注意:如果您的表单和表单集有冲突的字段名称,请使用 prefix="some_prefix": Django - Working with multiple forms

【讨论】:

  • 我完成了所有这些步骤,但使用的是 ActForm,而不是 GvtCompoForm(我想保存一个行为)。我确信它有效,因为我在其他字段中使用“表单”。我找到了一种解决方案,使用实例而不是表单,但我无法使用此解决方案验证或保存我的字段!
  • 我在示例中将 Gvt 更改为 Act。还添加了表单集以在表单中包含相关的 GvtCompo 对象。
  • 为什么要使用 GvtCompo 和 formset?我的字段会被验证和保存吗?
  • 如果我正确理解了您的问题,您希望在模板中显示一个表单,其中包含来自 Act 的所有字段以及来自相关 GvtCompo 的所有字段。正确的?在行为表单中,您可以选择 GvtCompo,但不能对其进行编辑。因此,您需要为每个相关的 GvtCompo 提供表单。这组表单就是表单集。在你的情况下,一组模型。 modelfroms 的全部目标是验证数据并将其保存到数据库中。所以有验证和保存。您需要从您的视图中调用它们。 formset.is_valid() 和 formset.save()。就像 form.is_valid() 和 form.save() 一样。
【解决方案2】:

在表单上循环时,应该是:

{% for field in form %}
    {% if field.name == "gvtCompo" %}
        {% for gvtCompo in form.instance.gvtCompo.all %}
            {{ gvtCompo.gvtCompo }}
        {% endfor %}
    {% endif %}
{% endfor %}

字段本身没有相关的field.gvtCompo

【讨论】:

  • 不起作用,什么都不显示;(。form.instance是什么意思?
  • 表示绑定模型实例。
  • 所以这就是我在编辑中所做的(我使用了我的实例行为)。然后我可以显示值,但没有表单字段了,所以没有验证也没有保存!
猜你喜欢
  • 1970-01-01
  • 2012-12-10
  • 2021-11-10
  • 2017-07-29
  • 2020-10-24
  • 1970-01-01
  • 1970-01-01
  • 2015-08-20
相关资源
最近更新 更多