97

我有

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 )

如何将 TextArea 小部件分配给管理界面中的“descr”字段?

upd:
仅 在管理界面中!

使用 ModelForm 的好主意。

4

9 回答 9

103

您将必须创建一个forms.ModelForm描述您希望该descr字段如何显示的内容,然后告诉admin.ModelAdmin使用该表单。例如:

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

form属性admin.ModelAdmin记录在官方 Django 文档中。这里有一个地方可以看

于 2009-01-10T05:57:05.513 回答
64

对于这种情况,最好的选择可能只是在模型中使用 TextField 而不是 CharField。您还可以覆盖类的formfield_for_dbfield方法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
于 2009-01-10T17:46:50.637 回答
35

Ayaz 有很多亮点,除了一点点变化(?!):

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)

因此,您无需重新定义 ModelForm 中的字段来更改它的小部件,只需在 Meta 中设置小部件 dict。

于 2011-06-05T20:00:40.510 回答
15

您不需要自己创建表单类:

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)

请参阅ModelAdmin.get_form

于 2018-05-25T04:29:16.693 回答
14

formfield您可以使用所需的方法对自己的字段进行子类化:

class CharFieldWithTextarea(models.CharField):

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

这将影响所有生成的表单。

于 2009-01-10T06:02:15.270 回答
8

如果您尝试更改 admin.py 上的 Textarea,这是对我有用的解决方案:

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)

如果您使用的是 MySQL DB,您的列长度通常会自动设置为 250 个字符,因此您需要运行 ALTER TABLE 来更改 MySQL DB 中的长度,以便您可以利用新的更大的 Textarea在您的 Admin Django 站点中。

于 2013-07-20T18:57:40.660 回答
5

代替 a models.CharField,使用models.TextFieldfor descr

于 2009-01-10T05:46:47.877 回答
5

您可以models.TextField为此目的使用:

class Sample(models.Model):
    field1 = models.CharField(max_length=128)
    field2 = models.TextField(max_length=1024*2)   # Will be rendered as textarea
于 2018-05-17T00:26:07.947 回答
3

想要扩展 Carl Meyer 的答案,直到现在它都非常有效。

我总是使用TextField代替CharField(有或没有选择)并在 UI/API 端而不是在数据库级别施加字符限制。要使其动态工作:

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

我有一个型号名称Post,其中title, slug&stateTextFields 并且state有选择。管理员定义如下所示:

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

认为寻找答案的其他人可能会发现这很有用。

于 2017-02-17T20:52:22.193 回答