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.

69
demandé sur Soviut 2009-01-10 08:10:23

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 .

83
répondu ayaz 2012-11-16 19:17:55

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
45
répondu Carl Meyer 2012-02-23 15:20:07

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.

30
répondu Gezim 2011-06-05 20:00:40

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.

12
répondu Alex Koshelev 2009-01-10 06:02:15

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.

5
répondu Aaron Lelevier 2013-07-20 18:57:40

au lieu de models.CharField , utilisez models.TextField pour descr .

2
répondu mipadi 2009-01-10 05:46:47

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 Posttitle , 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.

2
répondu tarequeh 2017-02-17 20:52:22

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
1
répondu Vikram Karandikar 2018-05-17 00:55:13

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 .

0
répondu x-yuri 2018-05-25 04:29:16