it-swarm.com.de

Django-Admin: CharField als TextArea

Ich habe

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 )

wie ordne ich das TextArea-Widget dem Feld 'descr' in der Administrationsoberfläche zu?

pd:
Nur in Admin der Benutzeroberfläche!

Gute Idee, ModelForm zu verwenden.

76
maxp

Sie müssen einen forms.ModelForm Erstellen, der beschreibt, wie das Feld descr angezeigt werden soll, und dann admin.ModelAdmin Anweisen, dieses Formular zu verwenden. Beispielsweise:

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

Das form -Attribut von admin.ModelAdmin Ist in der offiziellen Django Dokumentation dokumentiert. Hier ist ein Ort zum Ansehen .

88
ayaz

In diesem Fall ist es wahrscheinlich die beste Option, nur ein TextField anstelle von CharField in Ihrem Modell zu verwenden. Sie können auch die Methode formfield_for_dbfield Ihrer Klasse ModelAdmin überschreiben:

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
52
Carl Meyer

Ayaz hat bis auf eine kleine Änderung (?!) ziemlich genau das Richtige gefunden:

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)

Sie müssen also kein Feld in der ModelForm neu definieren, um das Widget zu ändern. Legen Sie einfach das Widgets-Dikt in Meta fest.

31
Gezim

Sie können Ihr eigenes Feld mit der erforderlichen formfield -Methode unterteilen:

class CharFieldWithTextarea(models.CharField):

    def formfield(self, **kwargs):
        kwargs.update({"widget": forms.Textarea})
        return super(CharFieldWithTextarea, self).formfield(**kwargs)

Dies wirkt sich auf alle generierten Formulare aus.

13
Alex Koshelev

Sie müssen die Formularklasse nicht selbst erstellen:

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)

Siehe ModelAdmin.get_form .

7
x-yuri

Wenn Sie versuchen, das Textarea auf admin.py zu ändern, ist dies die Lösung, die für mich funktioniert hat:

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)

Wenn Sie eine MySQL-Datenbank verwenden, wird Ihre Spaltenlänge in der Regel automatisch auf 250 Zeichen gesetzt. Führen Sie daher eine ALTER TABLE aus, um die Länge in Ihrer MySQL-Datenbank zu ändern, damit Sie den neuen, größeren Textbereich nutzen können habe in dir Admin Django site.

5
Aaron Lelevier

Anstelle einer models.CharField, benutze einen models.TextField für descr.

3
mipadi

Wollte auf Carl Meyers Antwort eingehen, die bis zu diesem Zeitpunkt perfekt funktioniert.

Ich verwende immer TextField anstelle von CharField (mit oder ohne Auswahl) und lege Zeichenbeschränkungen auf der UI/API-Seite und nicht auf DB-Ebene fest. Damit dies dynamisch funktioniert:

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

Ich habe einen Modellnamen Post wobei title, slug & stateTextFields sind und state Auswahlmöglichkeiten hat. Die Admin-Definition sieht folgendermaßen aus:

@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']

Dachten andere, die nach Antworten suchen, finden dies möglicherweise hilfreich.

3
tarequeh

Sie können models.TextField für diesen Zweck:

class Sample(models.Model):
    field1 = models.CharField(max_length=128)
    field2 = models.TextField(max_length=1024*2)   # Will be rendered as textarea
3
vk-code