如何过滤 Django ModelForm 中的外键选择? [英] How do I filter ForeignKey choices in a Django ModelForm?

查看:65
本文介绍了如何过滤 Django ModelForm 中的外键选择?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我的 models.py 中有以下内容:

Say I have the following in my models.py:

class Company(models.Model):
   name = ...

class Rate(models.Model):
   company = models.ForeignKey(Company)
   name = ...

class Client(models.Model):
   name = ...
   company = models.ForeignKey(Company)
   base_rate = models.ForeignKey(Rate)

即有多个 Companies,每个公司都有一个 RatesClients 范围.每个 Client 都应该有一个基本的 Rate,它是从它的父 Company's Rates 中选择的,而不是另一个 Company's Rates.

I.e. there are multiple Companies, each having a range of Rates and Clients. Each Client should have a base Rate that is chosen from it's parent Company's Rates, not another Company's Rates.

在创建用于添加 Client 的表单时,我想删除 Company 选项(因为已经通过Company 页面)并将 Rate 选项限制为该 Company.

When creating a form for adding a Client, I would like to remove the Company choices (as that has already been selected via an "Add Client" button on the Company page) and limit the Rate choices to that Company as well.

我如何在 Django 1.0 中解决这个问题?

How do I go about this in Django 1.0?

我当前的 forms.py 文件目前只是样板:

My current forms.py file is just boilerplate at the moment:

from models import *
from django.forms import ModelForm

class ClientForm(ModelForm):
    class Meta:
        model = Client

views.py 也是基本的:

from django.shortcuts import render_to_response, get_object_or_404
from models import *
from forms import *

def addclient(request, company_id):
    the_company = get_object_or_404(Company, id=company_id)

    if request.POST:
        form = ClientForm(request.POST)
        if form.is_valid():
            form.save()
            return HttpResponseRedirect(the_company.get_clients_url())
    else:
        form = ClientForm()

    return render_to_response('addclient.html', {'form': form, 'the_company':the_company})

在 Django 0.96 中,我能够通过在渲染模板之前执行以下操作来破解它:

In Django 0.96 I was able to hack this in by doing something like the following before rendering the template:

manipulator.fields[0].choices = [(r.id,r.name) for r in Rate.objects.filter(company_id=the_company.id)]

外键.limit_choices_to 似乎很有希望,但我不知道如何传入 the_company.id 并且我不清楚这是否可以在管理界面之外工作.

ForeignKey.limit_choices_to seems promising but I don't know how to pass in the_company.id and I'm not clear if that will work outside the Admin interface anyway.

谢谢.(这似乎是一个非常基本的要求,但如果我应该重新设计一些东西,我愿意接受建议.)

Thanks. (This seems like a pretty basic request but if I should redesign something I'm open to suggestions.)

推荐答案

ForeignKey 由 django.forms.ModelChoiceField 表示,它是一个 ChoiceField,其选择是一个模型 QuerySet.请参阅 ModelChoiceField 的参考.

ForeignKey is represented by django.forms.ModelChoiceField, which is a ChoiceField whose choices are a model QuerySet. See the reference for ModelChoiceField.

因此,为字段的 queryset 属性提供一个 QuerySet.取决于您的表单的构建方式.如果您构建一个显式表单,您将拥有直接命名的字段.

So, provide a QuerySet to the field's queryset attribute. Depends on how your form is built. If you build an explicit form, you'll have fields named directly.

form.rate.queryset = Rate.objects.filter(company_id=the_company.id)

如果采用默认的 ModelForm 对象,form.fields["rate"].queryset = ...

If you take the default ModelForm object, form.fields["rate"].queryset = ...

这是在视图中明确完成的.没有黑客攻击.

This is done explicitly in the view. No hacking around.

这篇关于如何过滤 Django ModelForm 中的外键选择?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆