Django - 限制选择字段到外表的查询集?

时间:2011-09-27 17:14:26

标签: django filtering django-queryset

我有两个模型如下:

System_Contact
    first_name
    last_name
    isOwner = CharField ('Y'/'N')
    isMainContact = CharField ('Y'/'N')

System
    mainContact = ForeignKey(System_Contact)
    owner = ForeignKey(System_Contact)
    billTo = ForeignKey(System_Contact)

因此,当我在网页中显示System表单时,用户可以从下拉菜单中选择mainContact ownerbillTo个联系人以保存到System模型。但是,我想过滤System表单中的选择字段,以便它们如下所示:

mainContact Select box: -- only show System_Contacts that have isMainContact = 'Y'
owner Select Box: -- only show Syste_Contacts that have isOwner = 'Y'

就像现在一样,我知道如何通过过滤查询集来限制选择框,但我不知道如何过滤相关的外键查询集。由于mainContactowner字段是外键,我需要过滤外表(System_Contact),而不是构建表单的表(System)< / p>

我知道如何过滤普通的非外键类型选择框,如下所示:

form.fields["some_field"].queryset = Some_Model.objects.filter(some_field="Foo")

我如何“扩展”这个以便过滤外表?

这是我目前正在尝试的,没有成功:

form.fields["mainContact"].queryset = System_Contact.objects.filter(isMainContact = 'Y')

由于

3 个答案:

答案 0 :(得分:2)

  

这是我目前正在尝试的,没有成功:

form.fields["mainContact"].queryset = System_Contact.objects.filter(isMainContact = 'Y')

您可以添加模型表单和视图吗?这看起来对我很好。

另一种方法是覆盖模型表单的__init__方法并在那里设置查询集。

class SystemForm(ModelForm):
    def __init__(self, *args, **kwargs):
        super(SystemForm, self).__init__(*args, **kwargs)
        self.fields["mainContact"].queryset = System_Contact.objects.filter(isMainContact = 'Y')
    class Meta:
        model = System

顺便说一句,我建议使用BooleanField代替CharField,选择“Y”和“N”。

答案 1 :(得分:1)

该语法看起来正确。您是收到错误还是仅仅过滤并向所有人展示?尝试使用System_Contact.objects.get(id = <some valid id>)来查看它是否只有一个或多个。如果它变得更多,也许它是从一个不同于预期的呼叫中填充的。

答案 2 :(得分:1)

这是令人尴尬的......

当我按照Alasdair's请求粘贴在我的视图和模型表单中时,我注意到了我的错误。这是我的(不正确的)观点:

def system_contacts(request, systemID):
    sys = System.objects.get(pk=systemID)
    if request.method == 'POST':
        form = System_Contacts_Form(request.POST, instance=sys)
        form.fields["systemOwner"].queryset = System_Contact.objects.filter(systemOwner__exact='Y')
        form.fields["mainContact"].queryset = System_Contact.objects.filter(isMainContact__exact = 'Y')
        if form.is_valid():
            form.save()
            return HttpResponseRedirect('/systems/')
    else:
        conts = Contact_List.objects.filter(systemID = sys.pk)
        form = System_Contacts_Form(instance=sys)
    return render_to_response('pages/systems/system_pages/contacts.html', {'sys':sys, 'form':form, 'conts':conts}, context_instance=RequestContext(request))

我已将form.fields["systemOwner"]...部分放在视图的POST部分,而不是视图的GET部分。

以下是我更正的观点:

def system_contacts(request, systemID):
    sys = System.objects.get(pk=systemID)
    if request.method == 'POST':
        form = System_Contacts_Form(request.POST, instance=sys)
        if form.is_valid():
            form.save()
            return HttpResponseRedirect('/systems/')
    else:
        conts = Contact_List.objects.filter(systemID = sys.pk)
        form = System_Contacts_Form(instance=sys)
        form.fields["systemOwner"].queryset = System_Contact.objects.filter(systemOwner__exact='Y')
        form.fields["mainContact"].queryset = System_Contact.objects.filter(isMainContact__exact = 'Y')
    return render_to_response('pages/systems/system_pages/contacts.html', {'sys':sys, 'form':form, 'conts':conts}, context_instance=RequestContext(request))

现在,我已更正的视图正常工作,并且过滤适用于表单上的select输入。没有你的帮助,我不会想到这一点。

干杯: - )