在django中,如何根据同一模型中的另一个字段限制异地的选择?

时间:2010-11-08 11:12:21

标签: django foreign-keys limit

我有这些模型(我已将字段数量限制为仅需要的那些)

class unit(models.Model):
    name = models.CharField(max_length=200)

class project(models.Model):
    name = models.CharField(max_length=200)

class location(address):
    project = models.ForeignKey(project)

class project_unit(models.Model):
    project = models.ForeignKey(project)         
    unit = models.ForeignKey(unit)

class location_unit(models.Model):
    project = models.ForeignKey(project)    
      #Limit the selection of locations based on which project has been selected
    location = models.ForeignKey(location)
      #The same here for unit. But I have no idea how.
    unit = models.ForeignKey(project_unit)       

我的新手头只是无法掌握如何限制location_unit模型中的两个字段,位置和单位,只显示在location_unit中引用所选项目的选项。我应该覆盖模型并在那里进行查询,还是可以使用limit_choices_to。无论哪种方式,我都尝试了两次

编辑:为了澄清,我想在Django Admin中发生这种情况。我也尝试过formfield_for_foreignkey,但仍然不适合我。

编辑2:

def formfield_for_foreignkey(self, db_field, request, **kwargs):
    if db_field.name == "unit":
        kwargs["queryset"] = project_unit.objects.filter(project=1)
        return db_field.formfield(**kwargs)
    return super(location_unit_admin, self).formfield_for_foreignkey(db_field, request, **kwargs)

以上代码段有效。但当然我不希望项目指向1.我如何引用模型project_id? 我试过这个:

kwargs["queryset"] = project_unit.objects.filter(project=self.model.project.project_id)

但这不起作用(实际上我尝试了很多变化,是的,我是django新手)

2 个答案:

答案 0 :(得分:9)

答案 1 :(得分:3)

您的formfield_for_foreignkey看起来可能是个好方向,但您必须意识到ModelAdmin(self)不会为您提供特定的实例。您必须从request(可能是django.core.urlresolvers.resolverequest.path

的组合中得出)

如果您只想在管理员中使用此功能(而不是一般的模型验证),则可以将自定义表单与模型管理类一起使用:

forms.py:

from django import forms

from models import location_unit, location, project_unit

class LocationUnitForm(forms.ModelForm):
    class Meta:
        model = location_unit

    def __init__(self, *args, **kwargs):
        inst = kwargs.get('instance')
        super(LocationUnitForm, self).__init__(*args, **kwargs)
        if inst:
            self.fields['location'].queryset = location.objects.filter(project=inst.project)
            self.fields['unit'].queryset = project_unit.objects.filter(project=inst.project)

admin.py:

from django.contrib import admin

from models import location_unit
from forms import LocationUnitForm

class LocationUnitAdmin(admin.ModelAdmin):
    form = LocationUnitForm

admin.site.register(location_unit, LocationUnitAdmin)

(只是在没有测试的情况下即时编写这些,所以不能保证它们能够正常工作,但它应该很接近。)