Django-Admin: CharField as TextArea
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 affecter le widget TextArea au champ 'descr' dans l'interface d'administration?
upd:
Dans Admin interface seulement!
bonne idée D'utiliser ModelForm.
9 réponses
vous devrez créer un forms.ModelForm
qui décrira comment vous voulez que le champ descr
soit affiché, puis dire admin.ModelAdmin
pour 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'attribut form
de admin.ModelAdmin
est documenté dans la documentation officielle de Django. Voici un endroit pour regarder .
dans ce cas, la meilleure option est probablement d'utiliser un champ Texte au lieu de CharField dans votre modèle. Vous pouvez également outrepasser la méthode formfield_for_dbfield
de votre classe ModelAdmin
:
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
Ayaz a à peu près exactement les mêmes, sauf pour une légère modification(?!):
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 la forme du modèle pour changer son widget, il suffit de définir les widgets dict dans Meta.
vous pouvez classer votre propre domaine avec nécessaire formfield
méthode:
class CharFieldWithTextarea(models.CharField):
def formfield(self, **kwargs):
kwargs.update(
"widget": forms.Textarea
)
return super(CharFieldWithTextarea, self).formfield(**kwargs)
cela affectera toutes les formes générées.
si vous essayez de changer le texte sur admin.py, c'est 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 un mysql DB, votre longueur de colonne sera généralement autoset à 250 caractères, donc vous voudrez exécuter une table ALTER pour changer la longueur en vous MySQL DB, afin que vous puissiez profiter de la Nouvelle plus grande Textarea que vous avez en vous Admin Django site.
au lieu de models.CharField
, utilisez models.TextField
pour descr
.
voulait développer la réponse de Carl Meyer, qui fonctionne parfaitement jusqu'à cette date.
j'utilise toujours TextField
au lieu de CharField
(avec ou sans choix) et j'impose des limites de caractères sur le côté UI/API plutôt qu'au niveau DB. Pour faire ce travail dynamiquement:
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
sont TextField
s et state
a des choix. Admin définition 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']
pensait que d'autres personnes à la recherche de réponses pourraient trouver cela utile.
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
vous n'avez pas besoin de créer vous-même la classe de formulaire:
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 .