Search code examples
pythondjangodjango-admininline-formset

Modifying spatial widget formsets on Django admin


I am using a TabularInline to reorganize some models in the Django 1.6 admin. I'm running into difficulty when I try to overwrite the default form that is being used. I've read the relevant portion of the docs here. Using formfield_overrides I've tried to change a form using this:

formfield_overrides = {
    models.PointField: {'widget': Textarea},
}

I am subclassing the admin.ModelAdmin using the following approach:

class DirectAdmin(admin.ModelAdmin):

    def get_inline_instances(self, request, obj=None):

        overrides = {
            models.PointField: {'widget': Textarea},
        }

        for inline in self.inlines:
            inline.formfield_overrides = overrides
            return inline(self.model, self.admin_site)

However, when I try this approach, I get the following error:

TypeError: zip argument #2 must support iteration

When I drop into this loop I can see that inline.formfield_overrides does exist as an empty dict, but I don't know what the correct values should be. Is this the correct approach? Is there any other way to modify these widgets when models are grouped using TabularInline?


Solution

  • Normally you should use formfield_overrides property in TabularInline or StackableInline defenition.

    For example:

    from django.contrib import admin
    from myapp.models import City, Shop
    
    class ShopInline(admin.TabularInline):
        formfield_overrides = {
            models.PointField: {'widget': Textarea},
        }
        model = Shop
    
    class CityAdmin(admin.ModelAdmin):
        inlines = [ShopInline,]
    

    But If you want set widget for all inlines:

    class DirectAdmin(admin.ModelAdmin):
    
    def get_inline_instances(self, request, obj=None):
    
        overrides = {
            models.PointField: {'widget': Textarea},
        }
        inline_instances = super(DirectAdmin, self).get_inline_instances(request, obj=obj)
        for inline in inline_instances:
            inline.formfield_overrides = overrides
        return inline_instances
    

    For better understanding please inspect get_inline_instance definition