j'ai
class Cab(models.Model):
name = models.CharField( max_length=20 )
descr = models.CharField( max_length=2000 )
class Cab_Admin(admin.ModelAdmin):
ordering = ('name',)
list_display = ('name','descr', )
# what to write here to make descr using TextArea?
admin.site.register( Cab, Cab_Admin )
comment attribuer le widget TextArea au champ 'descr' dans l'interface d'administration?
upd:
Dans l' interface d' administration uniquement!
Bonne idée d'utiliser ModelForm.
django
django-admin
maxp
la source
la source
Réponses:
Vous devrez créer un
forms.ModelForm
qui décrira comment vous voulez que ledescr
champ soit affiché, puis ditesadmin.ModelAdmin
d'utiliser ce formulaire. Par exemple:from django import forms class CabModelForm( forms.ModelForm ): descr = forms.CharField( widget=forms.Textarea ) class Meta: model = Cab class Cab_Admin( admin.ModelAdmin ): form = CabModelForm
L'
form
attribut deadmin.ModelAdmin
est documenté dans la documentation officielle de Django. Voici un endroit à regarder .la source
formfield_for_dbfield
votreModelAdmin
, voir ma réponse ci-dessous.django.core.exceptions.ImproperlyConfigured: Creating a ModelForm without either the 'fields' attribute or the 'exclude' attribute is prohibited
fields = '__all__'
sousclass Meta:
.get_form
méthode. Voyez ma réponse .Dans ce cas, la meilleure option est probablement simplement d'utiliser un TextField au lieu de CharField dans votre modèle. Vous pouvez également remplacer la
formfield_for_dbfield
méthode de votreModelAdmin
classe:class CabAdmin(admin.ModelAdmin): def formfield_for_dbfield(self, db_field, **kwargs): formfield = super(CabAdmin, self).formfield_for_dbfield(db_field, **kwargs) if db_field.name == 'descr': formfield.widget = forms.Textarea(attrs=formfield.widget.attrs) return formfield
la source
formfield.widget = forms.Textarea()
parformfield.widget = forms.Textarea(attrs=formfield.widget.attrs)
pour conserver tous les attributs générés automatiquement pour le TextField, merci!super()
. Sinon non.Ayaz a à peu près sa place, à l'exception d'un léger changement (?!):
class MessageAdminForm(forms.ModelForm): class Meta: model = Message widgets = { 'text': forms.Textarea(attrs={'cols': 80, 'rows': 20}), } class MessageAdmin(admin.ModelAdmin): form = MessageAdminForm admin.site.register(Message, MessageAdmin)
Donc, vous n'avez pas besoin de redéfinir un champ dans le ModelForm pour changer son widget, il suffit de définir les widgets dict dans Meta.
la source
Vous pouvez sous-classer votre propre champ avec la
formfield
méthode nécessaire :class CharFieldWithTextarea(models.CharField): def formfield(self, **kwargs): kwargs.update({"widget": forms.Textarea}) return super(CharFieldWithTextarea, self).formfield(**kwargs)
Cela prendra effet sur tous les formulaires générés.
la source
Vous n'avez pas besoin de créer la classe de formulaire vous-même:
from django.contrib import admin from django import forms class MyModelAdmin(admin.ModelAdmin): def get_form(self, request, obj=None, **kwargs): kwargs['widgets'] = {'descr': forms.Textarea} return super().get_form(request, obj, **kwargs) admin.site.register(MyModel, MyModelAdmin)
Voir ModelAdmin.get_form .
la source
Si vous essayez de modifier Textarea sur admin.py, voici la solution qui a fonctionné pour moi:
from django import forms from django.contrib import admin from django.db import models from django.forms import TextInput, Textarea from books.models import Book class BookForm(forms.ModelForm): description = forms.CharField( widget=forms.Textarea(attrs={'rows': 5, 'cols': 100})) class Meta: model = Book class BookAdmin(admin.ModelAdmin): form = BookForm admin.site.register(Book, BookAdmin)
Si vous utilisez une base de données MySQL, la longueur de votre colonne sera généralement définie automatiquement à 250 caractères, vous voudrez donc exécuter un ALTER TABLE pour modifier la longueur de votre base de données MySQL, afin de pouvoir profiter de la nouvelle zone de texte plus grande que vous avoir dans votre site Admin Django.
la source
Au lieu de a
models.CharField
, utilisez unmodels.TextField
fordescr
.la source
Vous pouvez utiliser
models.TextField
à cette fin:class Sample(models.Model): field1 = models.CharField(max_length=128) field2 = models.TextField(max_length=1024*2) # Will be rendered as textarea
la source
Je voulais développer la réponse de Carl Meyer, qui fonctionne parfaitement jusqu'à ce jour.
J'utilise toujours à la
TextField
place deCharField
(avec ou sans choix) et j'impose des limites de caractères côté interface utilisateur / API plutôt qu'au niveau DB. Pour que cela fonctionne de manière dynamique:from django import forms from django.contrib import admin class BaseAdmin(admin.ModelAdmin): """ Base admin capable of forcing widget conversion """ def formfield_for_dbfield(self, db_field, **kwargs): formfield = super(BaseAdmin, self).formfield_for_dbfield( db_field, **kwargs) display_as_charfield = getattr(self, 'display_as_charfield', []) display_as_choicefield = getattr(self, 'display_as_choicefield', []) if db_field.name in display_as_charfield: formfield.widget = forms.TextInput(attrs=formfield.widget.attrs) elif db_field.name in display_as_choicefield: formfield.widget = forms.Select(choices=formfield.choices, attrs=formfield.widget.attrs) return formfield
J'ai un nom de modèle
Post
oùtitle
,slug
&state
sontTextField
s et j'ai desstate
choix. La définition de l'administrateur ressemble à:@admin.register(Post) class PostAdmin(BaseAdmin): list_display = ('pk', 'title', 'author', 'org', 'state', 'created',) search_fields = [ 'title', 'author__username', ] display_as_charfield = ['title', 'slug'] display_as_choicefield = ['state']
Je pensais que d'autres personnes cherchant des réponses pourraient trouver cela utile.
la source
formfield_for_dbfield
documenté?