【问题标题】:Django: need to render form options manuallyDjango:需要手动渲染表单选项
【发布时间】:2019-04-01 15:15:18
【问题描述】:

我需要复制这个表格:

实时网页网址:

https://www.stickermule.com/products/die-cut-stickers

我一直在阅读有关如何手动呈现字段的文档,但无法手动呈现无线电输入及其值。

https://docs.djangoproject.com/en/2.1/topics/forms/#rendering-fields-manually

我的问题具体在于“选择数量部分”。

1) 我的表单继承自 forms.ModelForm 并且只包含数量,不包含成本(以美元为单位)也不包含节省部分。

这就是为什么我需要将数量放在一个标签中,从表单中拉出来,并在纯 html 中使用其他 2 个标签来手动输入成本和节省。

除非有办法将这些值作为其他字段放入模型中,但与字段数量相关(cantidad,西班牙语)。

所需的 HTML:

从这个页面复制我需要复制:

https://www.stickermule.com/products/die-cut-stickers

<form>
<div id="variants" class="product-option-group">      
 <legend>Select a size</legend>
 <ul id="variant-options" class="options">
   <li>
      <input id="variant_79" name="variant_id" readonly="" type="radio" value="79">
      <label for="variant_79"> 2" x 2"</label>
   </li>
   <li>
      <input id="variant_78" name="variant_id" type="radio" value="78">
      <label for="variant_78"> 3" x 3"</label>
   </li>
   <li>
      <input id="variant_80" name="variant_id" type="radio" value="80">
      <label for="variant_80"> 4" x 4"</label>
   </li>
   <li>
      <input id="variant_81" name="variant_id" type="radio" value="81">
      <label for="variant_81"> 5" x 5"</label>
   </li>
   <li>
      <input id="variant_77" name="variant_id" type="radio" value="77">
      <label for="variant_77"> Custom size</label>
   </li>
 </ul>
</div>
<div id="quantities">
   <legend>"Select a quantity"</legend>
   <ul>
      <li>
          <span class="table-cell">
            <input type="radio">
            <label>50</label>
          </span>
          <span id="price_50_id" class="table-cell  price">$57</span>
          <span class="table-cell savings"></span>
      </li>
      <li class=" quantity-item">
          <span class="table-cell">
              <input id="quantity_100" readonly="" name="quantity" type="radio" value="100">
              <label for="quantity_100" class=" quantity"> 100</label>
          </span>
          <span id="price_100_id" class="table-cell   price">$69</span>
          <span class="table-cell savings">Save 39%</span>
       </li>
  </ul>
</div>

models.py

class TamaniosCantidades(models.Model):
    TAMANIOS = (('2x2', '2" x 2"',), ('3x3', '3" x 3"',),
               ('4x4', '4" x 4"',), ('5x5', '5" x 5"',))

    CANTIDADES = (('50', '50',), ('100', '100',),
                ('150', '150',))

    tamanios = models.CharField(max_length=10, choices=TAMANIOS)
    cantidades = models.CharField(max_length=10, choices=CANTIDADES)

forms.py

class TamaniosCantidadesForm(forms.ModelForm):
    tamanios = forms.ChoiceField(choices=TAMANIOS, widget=forms.RadioSelect(), label='Selecciona un tamaño')
    cantidades = forms.ChoiceField(choices=CANTIDADES, widget=forms.RadioSelect(), label='Selecciona la cantidad')
    class Meta:
        model = TamaniosCantidades
        fields = ['tamanios', 'cantidades']

    def __str__(self):
        return self.tamanios

我的 HTML:

<form action="/post_url_tamanioscantidades/" method="post">
    {% csrf_token %}
    {{ tamanioscantidades_form.as_p }}
    <input type="submit" value="Submit"/>
</form>

总结:

我想调用如下字段:

<form>
   <div id="quantities">
     <legend> {{ tamanioscantidades_form.label }} </legend>

     <ul>
        <li>
        <span>
             <input type="radio" id="{{ tamanioscantidades_form.input1_id }}>
             <label> {{ tamanioscantidades_form.label }} </label>
        </span>
        <span>
             <label>$57</label>
        </span>
        <span>
             <label>""</label>
        </span>
       </li>
     </ul>
    </div>
</form>

更新 1:

有了答案,我现在可以渲染单选按钮,但不能渲染标签。

class TamaniosCantidadesForm(forms.ModelForm):
    tamanios = forms.ChoiceField(choices=TAMANIOS, widget=forms.RadioSelect(), label='Selecciona un tamaño')
    cantidades = forms.ChoiceField(choices=CANTIDADES, widget=forms.RadioSelect(), label='Selecciona la cantidad')
    class Meta:
        model = TamaniosCantidades
        fields = ['tamanios', 'cantidades']

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        self.cantidades_options = [option for option in self['cantidades']]

    def __str__(self):
        return self.tamanios

HTML:

第一个选项{{ tamanioscantidades_form.cantidades_options.0.label }} 的标签不会呈现

<ul>
  <h1>{{ tamanioscantidades_form.cantidades.label }}</h1> #This renders
  <li>
     <span> {{ tamanioscantidades_form.cantidades_options.0.tag }}
     <label> {{ tamanioscantidades_form.cantidades_options.0.label }} </label> #This does not render
   </span>
 </li>

【问题讨论】:

  • 我已经更新了答案,错别字已修复,您应该使用label 而不是choice_label

标签: django


【解决方案1】:

如果我没记错的话 RadioSelect 模板中的小部件可以被迭代。您可以在documentation 中阅读更多相关信息。

您知道下面的方法不是首选方法。不过,我提供它是因为我不确定您为什么无法建立与成本和节省的关系。

如果您提供有关数量、成本、节省的更多信息,我可能会提供帮助。


使用选项索引的解决方案

很遗憾,您提出的问题是开箱即用的。但是通过这样的事情可以相当容易地完成。

class TamaniosCantidadesForm(forms.ModelForm):
    tamanios = forms.ChoiceField(choices=TAMANIOS, widget=forms.RadioSelect(), label='Selecciona un tamaño')
    cantidades = forms.ChoiceField(choices=CANTIDADES, widget=forms.RadioSelect(), label='Selecciona la cantidad')
    class Meta:
        model = TamaniosCantidades
        fields = ['tamanios', 'cantidades']

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        self.cantidades_options = [option for option in self['cantidades']]

    def __str__(self):
        return self.tamanios

然后在你的模板中你应该能够做到:

<form>
   <div id="quantities">
     <legend> {{ tamanioscantidades_form.cantidades.label }} </legend>

     <ul>
        <li>
        <span>
             {{ tamanioscantidades_form.cantidades_options.0.tag }}
             <label> {{ tamanioscantidades_form.cantidades_options.0.choice_label }} </label>
        </span>
        <span>
             <label>$57</label>
        </span>
        <span>
             <label>""</label>
        </span>
       </li>
     </ul>
    </div>
</form>

【讨论】:

  • ty,这就是我需要的。但是您的答案中有一个错字,它是“cantidades”而不是“candidades”。 cantidades_options.0.label 不会渲染。请看我的更新。
猜你喜欢
  • 2017-06-02
  • 2019-03-17
  • 2019-07-08
  • 2020-05-08
  • 2014-09-23
  • 2020-08-16
  • 1970-01-01
  • 2017-05-12
  • 2017-09-15
相关资源
最近更新 更多