2012-04-11 64 views
1

我有场(命名为creator)的ModelForm其中一个是ForeignKey,所以{{ form.creator }} Django的渲染<select>标签是这样的:如何在Django中从ModelForm手动创建选择字段?

<select id="id_approver" name="approver"> 
    <option selected="selected" value="">---------</option> 
    <option value="1">hobbes3</option> 
    <option value="2">tareqmd</option> 
    <option value="3">bob</option> 
    <option value="4">sam</option> 
    <option value="5">jane</option> 
</select> 

但我想添加一个onchange事件属性,所以我可以使用AJAX后来做其他事情。我还想更改---------以表示其他内容,并显示审批者的全名,而不是他们的用户名。

那么有可能获得可能的批准者列表并生成我自己的选择选项?有点像

<select id="id_approver" name="approver" onchange="some_ajax_function()"> 
    <option select="selected" value="0">Choose a user</option> 
{% for approver in form.approver.all %} <!-- This won't work --> 
    <option value="{{ approver.pk }}">{{ approver.get_full_name }}</option> 
{% endfor %} 
</select> 

而且我还想到最审批的名单得到过大(如50),那么我会最终需要某种用于审批的可搜索自动完成场。那么我一定要写我自己的HTML。

万一有人需要它,我ModelForm看起来是这样的:

class OrderCreateForm(ModelForm) : 
    class Meta : 
     model = Order 
     fields = (
      'creator', 
      'approver', 
      'work_type', 
      'comment', 
     ) 

回答

1

ModelChoiceField documentation解释如何做到这一点。

要更改空标签:

empty_label 

    By default the <select> widget used by ModelChoiceField 
    will have an empty choice at the top of the list. You can change the text 
    of this label (which is "---------" by default) with the empty_label 
    attribute, or you can disable the empty label entirely by setting 
    empty_label to None: 

    # A custom empty label 
    field1 = forms.ModelChoiceField(queryset=..., empty_label="(Nothing)") 

    # No empty label 
    field2 = forms.ModelChoiceField(queryset=..., empty_label=None) 

关于你的第二个查询,它也解释了在文档:

The __unicode__ method of the model will be called to generate string 
representations of the objects for use in the field's choices; 
to provide customized representations, subclass ModelChoiceField and override 
label_from_instance. This method will receive a model object, and should return 
a string suitable for representing it. For example: 

class MyModelChoiceField(ModelChoiceField): 
    def label_from_instance(self, obj): 
     return "My Object #%i" % obj.id 

最后,通过一些定制的AJAX技术,使用attrs参数用于选择小部件(这是在ModelForm字段中使用的)。

最后,你应该有这样的事情:

creator = MyCustomField(queryset=..., 
         empty_label="Please select", 
         widget=forms.Select(attrs={'onchange':'some_ajax_function()'}) 
+0

因此,对于你上面的'creator'例子,我不得不从'fields'在'OrderCreateForm'删除'creator'并添加'creator = MyCustomField(...)'的代码行?或者我把'creator'作为'fields'列表的一部分(在'class Meta'下面)? – hobbes3 2012-04-11 15:13:55

+1

您应该删除它,因为您正在使用自定义字段进行渲染。 – 2012-04-11 17:34:07

+0

因为我需要更复杂的'creator'列表,它依赖于'User',所以我最终对模板中'creator'的'