Django Admin-remplacement du widget d'un champ de formulaire personnalisé

J'ai un champ de formulaire TagField personnalisé.

class TagField(forms.CharField):
    def __init__(self, *args, **kwargs):
        super(TagField, self).__init__(*args, **kwargs)
        self.widget = forms.TextInput(attrs={'class':'tag_field'})

Comme vu ci-dessus, il utilise un widget de champ de formulaire TextInput. Mais en admin, je voudrais qu'il soit affiché en utilisant le widget Textarea. Pour cela, il y a formfield_overrides hook mais cela ne fonctionne pas pour ce cas.

La déclaration admin est:

class ProductAdmin(admin.ModelAdmin):
    ...
    formfield_overrides = {
        TagField: {'widget': admin.widgets.AdminTextareaWidget},
    }

Cela n'a aucun effet sur le widget champ de formulaire et tags sont toujours rendus avec un widget TextInput.

Toute aide est très appréciée.

--
omat

23
demandé sur omat 2010-08-12 20:43:34

3 réponses

L'administrateur django utilise des widgets personnalisés pour plusieurs de ses champs. La façon de remplacer les champs consiste à créer un formulaire à utiliser avec L'objet ModelAdmin.

# forms.py

from django import forms
from django.contrib import admin

class ProductAdminForm(forms.ModelForm):
    def __init__(self, *args, **kwargs):
        super(ProductAdminForm, self).__init__(*args, **kwargs)
        self.fields['tags'].widget = admin.widgets.AdminTextareaWidget()

Ensuite, dans votre objet ModelAdmin, vous spécifiez le formulaire:

from django.contrib import admin
from models import Product
from forms import ProductAdminForm

class ProductAdmin(admin.ModelAdmin):
    form = ProductAdminForm

admin.site.register(Product, ProductAdmin)

Vous pouvez également remplacer le queryset à ce moment: pour filtrer les objets en fonction d'un autre champ dans le modèle, par exemple (puisque limit_choices_to ne peut pas gérer cela)

41
répondu Matthew Schinckel 2013-07-05 05:33:57

Vous pouvez remplacer les widgets de champ en étendant la classe META ModelForm depuis Django 1.2:

class ProductAdminForm(forms.ModelForm):
    class Meta:
        model = Product
        widgets = {
            'tags': admin.widgets.AdminTextareaWidget
        }

class ProductAdmin(admin.ModelAdmin):
    form = ProductAdminForm

Https://docs.djangoproject.com/en/dev/topics/forms/modelforms/#overriding-the-default-fields

31
répondu Murat Çorlu 2014-07-09 01:41:39

Essayez de changer votre champ comme ceci:

class TagField(forms.CharField):
    def __init__(self, *args, **kwargs):
        self.widget = forms.TextInput(attrs={'class':'tag_field'})
        super(TagField, self).__init__(*args, **kwargs)

Cela permettrait d'utiliser le widget qui vient de **kwargs. Sinon, votre champ utilisera toujours form.TextInput widget.

1
répondu Andrey Fedoseev 2010-08-12 17:02:27