在django中,如何限制基于同一模型中的另一个字段的外国人字段的选择?

时间:2022-06-01 20:52:43

I have these models (I have limited the number of fields to just those needed)

我有这些模型(我将字段的数量限制在只需要的范围内)

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)       

My newbie head just cannot grasp how to limit the two fields, location and unit, in the location_unit model to only show the choices which refers to the selected project in location_unit. Should I override the modelform and make a query there or can I use the limit_choices_to. Either way I have failed trying both

我的新手头脑就是不知道如何限制location_unit模型中的两个字段location和unit,只显示location_unit中指向所选项目的选项。我应该重写modelform并在那里进行查询,还是可以使用limit_choices_to。不管怎样,我都失败了。

Edit: Just to clarify, I want this to happen in the Django Admin. I have also tried formfield_for_foreignkey, but still a no go for me.

编辑:澄清一下,我希望这发生在Django管理员中。我也尝试过formfield_for_foreignkey,但仍然拒绝。

EDIT 2:

编辑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)

The above code snippet works. But of course I don't want the project to point to 1. How do I reference to the models project_id? I tried this:

上面的代码片段可以工作。当然,我不希望项目指向1。如何引用project_id模型?我试着这样的:

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

But that doesn't work (actually I have tried a lot of variations, yes I am a django newbie)

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

2 个解决方案

#1


9  

This is the answer, it is brilliant: https://github.com/digi604/django-smart-selects

这就是答案,非常精彩:https://github.com/digi604/django-smart select

#2


3  

Your formfield_for_foreignkey looks like it might be a good direction, but you have to realize that the ModelAdmin (self) won't give you a specific instance. You'll have to derive that from the request (possibly a combination of django.core.urlresolvers.resolve and request.path)

您的formfield_for_foreignkey看起来可能是一个好的方向,但是您必须认识到,ModelAdmin (self)不会给您一个特定的实例。您将不得不从请求(可能是django.core.urlresolvers的组合)中派生该请求。解决和request.path)


If you only want this functionality in the admin (and not model validation in general), you can use a custom form with the model admin class:

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

forms.py:

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:

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)

(Just wrote these on the fly with no testing, so no guarantee they'll work, but it should be close.)

(只是在没有测试的情况下动态地编写这些代码,因此不能保证它们能够工作,但应该很接近。)

#1


9  

This is the answer, it is brilliant: https://github.com/digi604/django-smart-selects

这就是答案,非常精彩:https://github.com/digi604/django-smart select

#2


3  

Your formfield_for_foreignkey looks like it might be a good direction, but you have to realize that the ModelAdmin (self) won't give you a specific instance. You'll have to derive that from the request (possibly a combination of django.core.urlresolvers.resolve and request.path)

您的formfield_for_foreignkey看起来可能是一个好的方向,但是您必须认识到,ModelAdmin (self)不会给您一个特定的实例。您将不得不从请求(可能是django.core.urlresolvers的组合)中派生该请求。解决和request.path)


If you only want this functionality in the admin (and not model validation in general), you can use a custom form with the model admin class:

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

forms.py:

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:

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)

(Just wrote these on the fly with no testing, so no guarantee they'll work, but it should be close.)

(只是在没有测试的情况下动态地编写这些代码,因此不能保证它们能够工作,但应该很接近。)