Django - UpdateView ModelForm在queryset字段

时间:2018-06-10 00:48:11

标签: python django python-3.x django-forms

我试图更新一个模型对象,其中一个值是从查询集派生的。对象创建工作完美 - 它使用传递给模板的查询集,然后在POST上将其保存到对象中。

我的问题:名为parent_jury的字段在模板中显示为空的选择字段。它不包含原始字段值。如何让它将初始字段值设置为对象中的内容并允许用户从查询集中的其他值中进行选择?

但现在我试图update这个对象。这是代码:

#forms.py

def __init__(self, *args, **kwargs):
    pk = kwargs.pop('pk')
    yr = kwargs.pop('yr')
    jr = kwargs.pop('jr') 

    self.customer_id = pk
    self.court_year_id = yr
    super().__init__(*args, **kwargs)

    # This prints the correct value for the the object I'm trying to update
    print("pr: ", Jury.objects.get(
        jury_id=jr).parent_jury)  

    # This is my latest attempt to get the initial value (or any value) to 
    # be presented in the modelform/template.
    self.fields['parent_jury'].initial = Jury.objects.get(
        jury_id=jr).parent_jury

除了上面的代码之外,我还试图使用以下方法提取正确的__init__()值:

#forms.py (other attempts)

self.fields['parent_jury'] = forms.ChoiceField(
    required = False,
    choices = Jury.objects.filter(
        customer_id=pk).filter(
        court_year_id = yr),
    initial = Juriy.objects.get(
        jury_id=jr).parent_jury)

我的模板镜像我的createview模板(可能导致部分问题)。

#template.html

<tr><td>Parent Jury:</td><td><select name="parent_jury">
    {% for item in form.parent_jury.field.queryset %}
        <option value="{{ item }}">{{ item }}</option>
    {% endfor %}
</select></td></tr>

我确实遇到了this,但它正在使用一个单独的过滤器类 - 我希望在__init__中处理。

很可能我的问题实际上在模板中 - 我遇到this,但仍然宁愿管理ModelForm内传递的内容(以及如何)。

后续问题:

OR ...是否可以将初始值传递给模板中的所有其他内容,然后将其编码到模板中?

更新我

我几乎已经弄明白了 - 以下forms.py __ini__()会将右choices传递给模板:

def __init__(self, *args, **kwargs):
    pk = kwargs.pop('pk')
    yr = kwargs.pop('yr')
    jr = kwargs.pop('jr') 

    self.customer_id = pk
    self.court_year_id = yr
    super().__init__(*args, **kwargs)
    print("pr: ", Juriy.objects.get(
        jury_id=jr).parent_jury)

    choices = list(Jury.objects.filter(
        client_id = pk).filter(
        court_year_id = yr).values_list('jury_name', 'jury_name'))

    print("choices: ", choices)
    self.fields['parent_jury'] = forms.ChoiceField(
        choices = choices,
        )

.values_list()我已包含'jury_name'两次以使列表项生效。只有一个值,下面的模板会抛出错误:not enough values to unpack (expected 2, got 1)。通过两个解决了这个问题。

在我的模板中:

<tr><td>Parent Jury:</td><td><select name="parent_jury">
    {% for item in form.parent_jury %}
        <option value="{{ item }}">{{ item }}</option>
    {% endfor %}
</select></td></tr>

#output
Thingy1
Thingy1
Thingy2
Thingy2
Thingy3
Thingy3

正如您所看到的,现在问题是表单上的select/option字段实际上复制了键条目。每个键在下拉菜单中显示两次。

我还在模板底部运行以下代码并获得正确的结果:

{% for item in form.parent_jurisdiction %}
    {{item}}
{% endfor %}

#output
Thingy1
Thingy2
Thingy3

我该如何解决?

更新II

我在下面的回答是错误的......虽然删除{{ item }}标签确实改变了选项,只包含一组选项 - 但它并没有在POST中传递 - 而是我在POST报告中得到这个:

parent_jury         '<option value='

所以,越来越近 - 视图是正确的,但所选择的选择不会被传回。

更新III

找到模板的正确构造...答案更新:

可以找到模板的原始答案here

1 个答案:

答案 0 :(得分:0)

最后一篇文章在模板中。

原始代码为:

<option value="{{ item }}">{{ item }}</option>

这导致value元素和label元素都包含在选项列表中。由于两者具有相同的值,因此它们(thingy或另一个thingy1)在POST中具有相同的结果。可以找到此select/option/iteration的构造here

#update code
<tr><td>Parent Jurisdiction:</td><td><select name="parent_jury">
    {% for val, item in form.fields.parent_jury.choices %}
            <option value="{{ item }}"{% if form.fileds.parent_jury.value == val%} selected{% endif %}>{{ item }}</option>
    {% endfor %}
</select></td></tr>

作为后续注释,在选项中使用queryset对象需要:

# passing queryset to select/option
<tr><td>Parent Jury:</td><td><select name="parent_jury">
    {% for item in form.parent_jury.field.queryset %}
        <option value="{{ item }}">{{ item }}</option>
    {% endfor %}
</select></td></tr>
相关问题