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

Bri*_*ian 11 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)       
Run Code Online (Sandbox Code Playgroud)

我的新手头只是无法掌握如何限制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)
Run Code Online (Sandbox Code Playgroud)

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

kwargs["queryset"] = project_unit.objects.filter(project=self.model.project.project_id)
Run Code Online (Sandbox Code Playgroud)

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

ete*_*ode 5

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


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

形式.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)
Run Code Online (Sandbox Code Playgroud)

管理员.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)
Run Code Online (Sandbox Code Playgroud)

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

  • 好的,这正是我想要的:) https://github.com/digi604/django-smart-selects (3认同)
  • 确实,这仅在编辑 location_unit 时有效,而不能创建新的 location_unit,因为在创建新的 location_unit 时,还没有“实例”,因此没有项目可以限制选择。您必须“保存并继续编辑”才能获得限制,或者实施某种 AJAX 来根据项目选择获取有效的选择(我过去也这样做过)。如果您认为自己已经找到了答案,请接受您的答案作为解决方案。谢谢。 (3认同)