代码之家  ›  专栏  ›  技术社区  ›  Bill Armstrong

django-updateview modelform在queryset字段上设置初始值

  •  0
  • Bill Armstrong  · 技术社区  · 8 年前

    我正在尝试更新一个模型对象,其中一个值是从queryset派生的。对象创建工作得很好-它使用一个传递给模板的queryset,然后在post中保存到对象中。

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

    但现在我想 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 .

    后续问题:

    或者…是否可以将初始值与其他内容一起传递到模板中,然后将其编码到模板中?

    更新我

    我几乎想明白了-这是 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
    

    我该怎么解决?

    更新二

    我下面的回答是错误的…尽管 {{ item }} 实际上,label确实会将选项更改为只包含一组选项—它不会传入post—相反,我会在post报告中看到这一点:

    parent_jury         '<option value='
    

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

    更新三

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

    原来这样回答模板可以找到 here .

    1 回复  |  直到 8 年前
        1
  •  0
  •   Bill Armstrong    8 年前

    最后一张是在模板中。

    原始代码如下:

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

    导致了 value 元素和 label 要包含在选项列表中的元素。既然两者都有相同的价值( thingy 或者其他 thingy1 )在帖子里也有同样的结果。这个的构造 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>