【问题标题】:Trying to access ModelForm field modelChoice choices in Django template尝试在 Django 模板中访问 ModelForm 字段 modelChoice 选项
【发布时间】:2013-01-13 20:08:02
【问题描述】:

我正在生成 ModelForms,并希望对它们在我的模板中的输出方式进行一些精细控制。具体来说,我需要在每个选择列表中的每个单选按钮的末尾添加一些标记。

代码:

# order-form.html

{% load catname %}
<form id = "order-form">
{% for form in forms %}
<div id="gun-{{ forloop.counter }}">
    {% for field in form.fields %}
        <div id="{{ field }}-item" class="item">
            <h3>{{ field|catname }}</h3>
            {% for choice in form.field.choices %} {# <-- Help me out here #}
                {{ choice.id }}
                {{ choice.title }}
            {% endfor %}
        </div>
    {% endfor %}
{% endfor %}
<button type="submit" id="standard-gun-form-submit">Continue to next step</button>
</form>

# views.py
def get_form(request):
    if request.method == 'POST':
        if request.POST['gun_type'] == 'standard':
            forms = [StandardGunForm(prefix=p) for p in range(0,2)]
            return render_to_response('main/order-form.html', {'forms' : forms,}, RequestContext(request))

# forms.py

class StandardGunForm(ModelForm):
    def __init__(self, *args, **kwargs):
        super(StandardGunForm, self).__init__(*args, **kwargs)  
        for field in self.fields: 
            if isinstance(self.fields[field], ModelChoiceField):
                self.fields[field].empty_label = None

    class Meta:
        model = BaseGun
        widgets = {
            'FrameTuning' : RadioSelect(),
            'FrameConnection' : RadioSelect(),
        }
        exclude = ('price')

Endgame:看起来像这样的标记

<form id="foo">
<div class="category">
    <div class="item">
        <input type="radio" name="srsbzns" value="1">Option 1</input>
        <img src="http://placekitten.com/150/150">
        <p>Other foo here</p>
    </div>
    <div class="item">
        <input type="radio" name="srsbzns" value="2">Option 2</input>
        <img src="http://placekitten.com/150/150">
        <p>Other foo here</p>
    </div>
    <div class="item">
        <input type="radio" name="srsbzns" value="3">Option 3</input>
        <img src="http://placekitten.com/150/150">
        <p>Other foo here</p>
    </div>  
</div>
</form>

从 shell 中返回我想要的东西

>>> forms = [StandardGunForm(prefix=p) for p in range(0,2)]\
>>> forms[0].fields['frame_tuning'].choices.queryset

我很惊讶这被证明如此具有挑战性!

奖励:我启用了 DEBUG = True 和 Django 调试工具栏。是否可以将变量转储到浏览器中,以便我可以在深入研究时看到这些东西的样子?

谢谢!

【问题讨论】:

  • 我猜是 {% for id, title in field.choices %},但为什么不只是 {{ field }} 使用自定义小部件?如果您需要自定义输出,请编写自定义小部件... :-)
  • 是的,可能是自定义小部件

标签: django django-forms django-templates


【解决方案1】:

您可以访问每个选项的底层模型实例:

{% for choice, label in form.field_name.field.choices %}
    {{ choice.value }}
    {{ choice.instance }} 
    {{ choice.instance.instance_attribute }}
    {{ label }}
{% endfor %}

【讨论】:

    【解决方案2】:

    很晚了,但我现在正在阅读,这对我有用

    {% for field in form %}
      {% for x, y in field.field.choices %}
        {{x}}
        {{y}}
      {% endfor %}
    {% endfor %}

    其中“x”是 id 或代码,“y”是可读值或标题。

    【讨论】:

      【解决方案3】:

      我不得不做类似的事情,也开始了这条路。我想从 ModelChoiceField 创建表行,其中每列都有模型实例的不同字段(然后我允许通过 JavaScript 过滤表行)。

      我在 Django 文档中找不到它,但是快速浏览 Django 源代码就可以找到方法。您可以像这样访问查询集以访问模型实例:

      <form action="{% url 'some_view' %}" method="post">
          {% csrf_token %}
          {% if form.non_field_errors %}
              {{ form.non_field_errors }}
          {% endif %}
      
          {% for field in form %}
              {{ field.label }}
      
              {% if field.field.choices %}
                {% for model_instance in field.field.choices.queryset %}
                  {{ model_instance.id }}
                {% endfor %}
              {% else %}
                {{ field }}
              {% endif %}
      
              {% if field.errors %}
                  {{ field.errors|striptags }}
              {% endif %}
      
          {% endfor %}
      
          <button type="submit">Submit</button>
      </form>
      

      然而,此时我们已经分解了闪亮的小部件(在我的例子中是 CheckboxSelectMultiple),并且必须使用模板代码重新组装 HTML 表单输入。我发现没有直接的方法可以同时遍历 ModelChoiceField 来访问模型实例字段并获取选项的 HTML 表单标签。

      也许有办法,但我放弃了尝试并构建了自己的 HTML 表单,在视图中处理所有 POST 数据。这样就容易多了。 ModelForms 非常好用且方便,但将它们用于它们不是为它们而构建的东西最终会变得更加困难。

      我想我会发布这个,以防有人出于其他原因尝试这样做。希望对您有所帮助。

      【讨论】:

        【解决方案4】:
        {% for choice in form.field.choices %} {# <-- Help me out here #}
                    {{ choice.id }}
                    {{ choice.title }}
        {% endfor %}
        

        看看你在这里做什么,你实际上是在每次循环中都试图访问一个名为“field”的字段,这可能不存在。

        您需要获取正在迭代的字段对象,并访问其上的选择属性。

        {% for field in form.fields %}
           {% for choice in field.choices %}
        

        【讨论】:

        • 唉,这也行不通。在发布到这里之前,我尝试了很多组合。我想我会简单地编写一个自定义小部件并在那里生成我的标记。
        • starsinmypockets,试试 field.field.choices
        猜你喜欢
        • 1970-01-01
        • 2010-12-11
        • 1970-01-01
        • 2013-03-16
        • 2016-11-26
        • 2021-10-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多