3

MyModel has a mptt's TreeForeignKey field category. In the admin of MyModel, how can I disable some options in the Select widget of this category field?

Thanks you

class Category(MPTTModel):
    parent = TreeForeignKey('self', blank=True, null=True, related_name='children')
    nom = models.CharField(max_length=100)

class MyModel(models.Model):
    category = TreeForeignKey(Category)
    # more fields
jul
  • 36,404
  • 64
  • 191
  • 318

1 Answers1

10

I had to overwrite MyModelAdminForm and use a forms.ChoiceField field with a SelectWithDisabled widget for the category field. In my case I only wanted the leaves of the tree to be selectable.

class MyModelAdminForm(forms.ModelForm):

    class Meta:
        model = MyModel

    def __init__(self, *args, **kwargs):
        self.level_indicator = kwargs.pop('level_indicator', u'---')
        super(MyModelAdminForm, self).__init__(*args, **kwargs)

        queryset = Category.objects.all()
        mptt_opts = queryset.model._mptt_meta
        queryset = queryset.order_by(mptt_opts.tree_id_attr, mptt_opts.left_attr)

        choices = []
        for item in queryset:
            level = getattr(item, item._mptt_meta.level_attr)
            value = item.id
            label = mark_safe(conditional_escape(self.level_indicator) * level + smart_unicode(item.nom))
            if item.is_leaf_node():
                choices.append((value, label))
            else:
                choices.append((value, {'label': label, 'disabled': True}))

        self.fields['category'] = forms.ChoiceField(choices=choices, widget=SelectWithDisabled)


class MyModelAdmin(admin.ModelAdmin):
    form = MyModelAdminForm

samsic_site.register(MyModel, MyModelAdmin)
jul
  • 36,404
  • 64
  • 191
  • 318