【发布时间】:2018-07-18 18:09:20
【问题描述】:
我有一个 ModelForm,它使用 CheckboxSelectMultiple 小部件来表示来自 ManyToManyField 的数据。默认情况下,这将呈现一个复选框列表,其标签设置为相关模型的__str__ 方法的返回值。但是,除了小部件提供的choice_label 之外,我希望显示来自相关模型中其他字段的数据。例如考虑下面的实现:
models.py
from django.db import models
class Category(models.Model):
name = models.CharField(max_length=50)
def __str__(self):
return self.name
class Item(models.Model):
name = models.CharField(max_length=100)
category = models.ForeignKey('Category', on_delete=models.CASCADE)
def __str__(self):
return self.name
class Order(models.Model):
items = models.ManyToManyField('Item')
forms.py
from django import forms
from .models import Order
class OrderForm(forms.ModelForm):
class Meta:
model = Order
fields = ['items']
widgets = {'items': forms.widgets.CheckboxSelectMultiple}
模板.html
{% for item in form.items %}
<tr>
<td>{{ item.tag }}</td>
<td>{{ item.choice_label }}</td>
<td>{{ item.category }}</td>
</tr>
{% endfor %}
这里的问题是 template.html 的 {{ item.category }} 部分。当使用{% for item in form.items %} 循环遍历所有项目复选框时,item 的类型为BoundWidget,而不是Item。这就是提供tag 和choice_label 属性来呈现表单复选框的原因。我的问题是BoundWidget 似乎没有对复选框所代表的Item 实例的任何引用,这将允许我访问任何其他模型数据,例如项目所在的类别。有没有解决办法?
编辑:
我能想到的唯一方法是:
模板标签/app_tags.py
from django import template
from models import Item
register = template.Library()
@register.inclusion_tag('app/order_item_table.html')
def show_item_table(items):
item_objs = []
for item in items:
id = item.data['value']
obj = Item.objects.get(id=id)
item_objs.append((item, obj))
return {'items': item_objs}
order_item_template.html
{% for item, obj in items %}
<tr>
<td>{{ item.tag }}</td>
<td>{{ item.choice_label }}</td>
<td>{{ obj.category }}</td>
</tr>
{% endfor %}
模板.html
{% load app_tags %}
{% show_item_table form.items %}
但这似乎令人难以置信,我真的很想知道是否有更好的方法来做到这一点?
【问题讨论】:
-
这有什么更新吗?我遇到了同样的问题。我正在考虑访问小部件中的查询集,但我不知道如何
标签: python django django-forms django-templates