Domanda

I have a CarType that has a ForeignKey BodyMaterial in my models.py:

class BodyMaterial(models.Model):
    location                = models.ForeignKey('CarType')
    name                    = models.CharField(max_length=255)

class CarType(models.Model):
    name                    = models.CharField(max_length=255)
    default_body_material   = models.ForeignKey(BodyMaterial, null = True, blank = True, default = "", limit_choices_to={'location__exact': 1})

BodyMaterial is an Inline in CarType in my admin.py:

class BodyMaterial_Inline(admin.StackedInline):
    model = BodyMaterial
    extra = 1

class CarType_Admin(admin.ModelAdmin):
    inlines = [BodyMaterial_Inline]

admin.site.register(CarType, CarType_Admin)

I would like to filter the ForeignKey for default_body_material to show only the relevant BodyMaterials (the ones that appear/added on the same admin page). For example, I created a 2 seat CarType and in the same page added some BodyMaterials. Then I create an SVU CarType and some other BodyMaterials. When I go back to the 2 seat CarType, I would like to see only the relevant BodyMaterials in the drop-down for default_body_material.

I try to filter using limit_choices_to on the id. So I'm doing this using post_init because the id for the object in determined in runtime:

def setID(**kwargs):
    instance = kwargs.get('instance')
    default_body_material = instance._meta.get_field_by_name('default_body_material')[0]
    default_body_material.limit_choices_to = {'location__exact': instance.id}

post_init.connect(setID, CarType)

Unfortunately, that does nothing. What am I missing? Is there a beter why of filtering ForeignKey for my purposes (this is probably very basic)?

Note that this question is only for the admin interface.

È stato utile?

Soluzione

Just use a custom ModelForm:

class CarTypeAdminForm(forms.ModelForm):
    def __init__(self, *args, **kwargs):
        super(CarTypeAdminForm, self).__init__(*args, **kwargs)
        # Can't limit it until instance has been saved at least once
        if self.instance.pk:
            self.fields['default_body_material'].queryset = \
                self.fields['default_body_material'].queryset \
                    .filter(location=self.instance)

class CarTypeAdmin(admin.ModelAdmin):
    form = CarTypeAdminForm
    ...

Altri suggerimenti

You want to look at overriding the queryset function for your inline.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top