如何根据AdminForm中的选定对象来限制Django Admin中InlineForm的ForeignKeyField的选择。
问题是InlineForm对相关的管理表单不了解有关该对象的任何信息。
答案 0 :(得分:0)
您必须将父对象从InlineAdmin传递到FormSet,再传递给实际的Form。花了我好一会儿才知道。
在下面的示例中,CalibrationCertificateData
与CalibrationCertificate
有关,我只想显示与SensorCategory相关的Quantities
。
from django.contrib import admin
from django.forms import ModelForm, BaseInlineFormSet
from src.admin import site_wm
from . import models
from quantity_management.models import QuantitySensor
# Register your models here.
site_wm.register(models.CalibrationInstitute, site=site_wm)
class CertDataAdminForm(ModelForm):
class Meta:
model = models.CalibrationCertificateData
fields = "__all__"
def __init__(self, *args, **kwargs):
"""
Make sure that we only show the Quantites that are related to the selected Cert>Sensor>Category
"""
self.parent_obj = None
if 'parent_obj' in kwargs:
self.parent_obj = kwargs['parent_obj']
del kwargs['parent_obj']
super().__init__(*args, **kwargs)
if self.parent_obj:
# Do the actual filtering according to the parent object
category_id = self.parent_obj.Sensor.Category_id
self.fields['Quantity'].queryset = QuantitySensor.objects.filter(Sensor_id=category_id)
class CertDataAdminFormSet(BaseInlineFormSet):
form = CertDataAdminForm
def get_form_kwargs(self, index):
"""
Make sure the form knows about the parent object
"""
kwargs = super().get_form_kwargs(index)
if hasattr(self, 'parent_obj') and self.parent_obj:
kwargs['parent_obj'] = self.parent_obj
return kwargs
class CalibrationDataAdmin(admin.StackedInline):
model = models.CalibrationCertificateData
extra = 0
form = CertDataAdminForm
formset = CertDataAdminFormSet
def get_formset(self, request, obj=None, **kwargs):
"""
give the formset the current object, so it can limit the selection choices according to it
"""
formset = super().get_formset(request, obj, **kwargs)
if formset is not None:
formset.parent_obj = obj
return formset
def formfield_for_foreignkey(self, db_field, request, **kwargs):
print(self.parent_model)
return super().formfield_for_foreignkey(db_field, request, **kwargs)
@admin.register(models.CalibrationCertificate, site=site_wm)
class CalibrationCertificateAdmin(admin.ModelAdmin):
inlines = (
CalibrationDataAdmin,
)