Django使用ModelChoiceField显示ManyToMany模型字段

时间:2013-07-05 08:34:16

标签: python html django django-orm

我有一个包含不同字段的“父”模型,其中一个是一个ManyToMany字段,引用另一个模型(反过来,它有几个字段)。

我想显示一个ModelChoiceField,其中包含“父”模型所具有的ManyToMany对象的名称。

models.py

class Media(models.Model):
    name = models.CharField(max_length=20, default='')
    ident = models.CharField(max_length=20, default='')
    def __unicode__(self):
        return self.name

class Parent(models.Model):
    name = models.CharField(max_length=200, default='')
    media = models.ManyToManyField(Media)
    def __unicode__(self):
        return self.name

为此,我在views.py上有:

l = Parent.objects.all().order_by('name')
for parent in l:
    if parent.name == unicode(request.session['current_parent']) 
        break
m = forms.ModelChoiceField(parent.media.all(), widget=forms.Select())
return render_to_response('tab.html', {'media_list':m}) 

但是我在html上看到的是这句话:<django.forms.models.ModelChoiceField object at 0x03294570>

我该怎样做才能正确呈现列表?

1 个答案:

答案 0 :(得分:1)

您不能单独显示表单字段。它必须实际上是表单的一部分,您必须在将表单传递给模板之前进行实例化。

另请注意,获取父级的方法可怕效率低下:您实例化数据库中的每个父级,只是为了得到一个。你应该直接查询。

class ParentForm(forms.Form):
     media = forms.ModelChoiceField(Media.objects.none(), widget=forms.Select())
     def __init__(self, *args, **kwargs):
         parent = kwargs.pop('parent')
         super(ParentForm, self).__init__(*args, **kwargs)
         self.fields['media'].queryset = parent.media.all()

def my_view(request):
    parent = Parent.objects.filter(name=request.session['current_parent'])
    form = ParentForm(parent=parent)
    return render_to_response('tab.html', {'media_form': form}) 

或者,将父对象传递给模板然后手动构造选择框可能更容易:

 <select name='media'>
 {% for media in parent.media.all %}
     <option value='{{ media.ident }}'>{{ media.name }}</option>
 {% endfor %}
 </select>