Django-Filter:{{ field.value }} 在呈现表单字段时为空

Django-Filter: {{ field.value }} is Empty when rendering form fields

我正在使用 Django-Filter library !important. For tags, I'm using Django-taggit

我构建了以下 filter.py:

class TaskFilter(django_filters.FilterSet):
    tags = django_filters.ModelMultipleChoiceFilter(widget=forms.CheckboxSelectMultiple, queryset=Task.tags.most_common())

    class Meta:
        model = Task
        fields = ['tags']

但是,当我将此 filter 传递给模板时,它没有正确呈现标签。特别是 {{ field.value }} 是空的。让我们看看以下案例:


案例 1.

# template.html
{{ filter.form.tags.errors }}
{% for field in filter.form.tags %}
<label for="{{ field.id_for_label }}"></label>
{{ field.value }}
{% endfor %}

# out
<label for="id_tags_0"></label>
<label for="id_tags_1"></label>
<label for="id_tags_2"></label>

案例 2.

# template.html
{{ filter.form.tags.errors }}
{% for field in filter.form.tags %}
<label for="{{ field.id_for_label }}"></label>
{{ field }}
{% endfor %}

# out
<label for="id_tags_0"></label>
<label for="id_tags_0"><input type="checkbox" name="tags" value="4" id="id_tags_0">Tag 1</label>
<label for="id_tags_1"></label>
<label for="id_tags_1"><input type="checkbox" name="tags" value="1" id="id_tags_1">Tag 2</label>
<label for="id_tags_2"></label>
<label for="id_tags_2"><input type="checkbox" name="tags" value="2" id="id_tags_2">Tag 3</label>

案例 3.

# template.html
{{ filter.form.tags.errors }}
{% for field in filter.form.tags %}
{{ field }}
{{ field.label_tag }}
{% endfor %}

#out
<label for="id_tags_0"><input type="checkbox" name="tags" value="4" id="id_tags_0">Tag 1</label>
<label for="id_tags_1"><input type="checkbox" name="tags" value="1" id="id_tags_1">Tag 2</label>
<label for="id_tags_2"><input type="checkbox" name="tags" value="2" id="id_tags_2">Tag 3</label>

我想了解为什么会这样。为什么我无法获取值 as stated in the docs

复制步骤

pip install django-filter + add 'django_filters' to APPS
pip install django-taggit + add 'taggit' to APPS

# models.py
class Task(models.Model):
    title = models.CharField(max_length=100, blank=False)
    tags = TaggableManager()

# Use the API to create an object.
t = Task.objects.create(title="Title")
t.tags.add("Tag 1","Tag 2")

# views.py
def view(request):
    f = TaskFilter(request.GET, queryset=Task.objects.all())
    return render(request, 'template.html', {'filter': f}

当您遍历 filter.form.tags 时,您不是在遍历一组表单字段,而是遍历 tags 字段的一组单独选择。这就是 field.value 不起作用的原因。

这应该可以代替:

{{ filter.form.tags.errors }}
{% for choice in filter.form.tags %}
    <label for="{{ choice.id_for_label }}"></label>
    {{ choice.tag }}
{% endfor %}

其中 tag 是存在于每个选项上的属性,它将呈现该选项的复选框输入。

这在 RadioSelect 的文档中有记录:

To get more granular, you can use each radio button’s tag, choice_label and id_for_label attributes.

再往下看,CheckBoxSelectMultiple 的文档说同样的逻辑也适用于它。