【问题标题】:Django Inline Formset - possible to follow foreign key relationship backwards?Django Inline Formset - 可以向后遵循外键关系吗?
【发布时间】:2017-11-06 20:18:01
【问题描述】:

我对 django 很陌生,所以如果有一个明显的答案,我深表歉意。

假设你有以下三个模型:

models.py

class Customer(models.Model):
    name = models.CharField()
    slug = models.SlugField()

class Product(models.Model):
    plu = models.Charfield()
    description = models.Charfield()

class Template(models.Model):
    customer = models.ForeignKey(Customer)
    product = models.ForeignKey(Product)
    price = models.DecimalField()

内联表单集看起来像:

TemplateFormSet = inlineformset_factory(Customer, Template, extra=0, 
                fk_name='customer', fields=('price'))

是否可以向后跟随模板表单集的产品外键,以便您可以在同一个表中显示 plu 和描述字段?

例如这样的:

<table>
  <tbody>
  {% for obj in customer.template_set.all %}
    <tr>
      <td>{{ obj.product.plu }}</td>
      <td>{{ obj.product.description }}</td>
      <td>{% render_field formset.form.price class="form-control form-control-sm" %}</td>
    </tr>
  {% endfor %}
  </tbody>
</table>

表单集的字段与上面的 html 一起出现,但来自绑定表单实例的数据没有出现,我无法通过编辑空字段来保存。

我也在下面尝试过,但是每个对象都会重复每个表单集(对于 x 个表单集,有 x*x 行):

<tbody>
{% for obj in customer.template_set.all %}
  {% for form in formset %}
    <tr>
      <td>{{ obj.product.plu }}</td>
      <td>{{ obj.product.description }}</td>
      <td>{% render_field form.price class="form-control" %}</td>
    </tr>
  {% endfor %}
{% endfor %}
</tbody>

Basically I'm trying to go from the top portion of the image to the bottom

【问题讨论】:

    标签: python django python-3.x


    【解决方案1】:

    formset 功能仅用于显示表单,但您可以创建一个自定义表单,显示具有 readonly 功能的 2 个字段,例如:

    class your_form(models.ModelForm):
         class Meta()
            model = Template
            fields = ['price', 'product']
    
         def __init__(self, *args, **kwargs):
             super(ItemForm, self).__init__(*args, **kwargs)
             self.fields['product'].widget.attrs['readonly'] = True
    
    TemplateFormSet = inlineformset_factory(Customer, Template, extra=0, 
                    fk_name='customer', form=your_form)
    

    这是我最好的尝试,如果您想同时显示两者,请尝试在您的模型中返回类似:

    class Product(models.Model):
        plu = models.Charfield()
        description = models.Charfield()
    
        def __str__(self, *args, **kwargs):
            a = '<td>' + self.plu + '</td><td>' + self.plu '</td>' 
            return self.plu + self.description # Or return 'a'
    

    【讨论】:

    • 感谢您的回答,但我希望在表格中添加相当多的字段,这样做很难做到。
    【解决方案2】:

    虽然我不确定它是最有效的方式,但我设法让它工作。如果有人有更好的方法,请告诉我。

    {{ formset.management_form }}
    <table>
      <thead>
      ...
      </thead>
      <body>
      {% for obj in customer.template_set.all %}
        {% with forloop.counter as outer_counter %}
          {% for form in formset %}
            {% if forloop.revcounter == outer_counter %}
              {% for hidden in form.hidden_fields %} {{ hidden }} {% endfor %}
              <tr>
                <td>{{ obj.product.plu }}</td>
                <td>{{ obj.product.description }}</td>
                <td>{% render_field form.price class="form-control" %}</td>
              </tr>
            {% endif %}
          {% endfor %}
        {% endwith %}
      {% endfor %}
      </tbody>
    </table>
    

    还应该提到我正在使用 django-widget-tweaks,这是 {% render_field %} 的来源。

    更新(正确方式):

    {% for template in customer.template_set.all %}
      {% for form in formset %}
        {% if form.instance.id == template.pk %}
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-11-16
      • 2020-09-16
      • 2017-05-01
      • 1970-01-01
      • 2013-11-03
      • 2011-11-25
      • 2012-10-15
      • 2015-10-10
      相关资源
      最近更新 更多