2009-01-10 58 views
65

Django的管理:CharField为文本区域

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。

+1

接受的答案是为了modficiation只是一个领域的巨大矫枉过正!人们按照卡尔迈耶的这个答案为简单性的目的:http://stackoverflow.com/questions/430592/django-admin-charfield-as-textarea#431412 – andi 2014-10-30 10:05:08

回答

78

您将不得不创建一个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 

admin.ModelAdminform属性Django官方文档中记录。这里是one place to look at

2

而不是models.CharField,使用models.TextField代替descr

+4

不幸的是,max_length =被Django完全忽略在一个TextField,所以当你需要字段长度验证时(例如让秘书输入事件摘要),获得它的唯一方法是使用CharField。但CharField是短路输入300个字符的方式。因此,ayaz解决方案。 – shacker 2009-04-21 23:45:40

+0

绝对!谢谢。 – 2012-01-26 00:58:20

+2

这不是一个好的答案,因为它改变了数据库。更改窗口小部件的目的是改变显示字段的方式,而不是改变数据库模式 – 2013-02-14 21:11:02

12

您可以根据需要formfield方法继承自己的领域:

class CharFieldWithTextarea(models.CharField): 
    def formfield(self, **kwargs): 
     kwargs.update(
      "widget": forms.Textarea 
     ) 
     return super(CharFieldWithTextarea, self).formfield(**kwargs) 

这将在所有生成的形式影响。

45

对于这种情况,最好的选择可能只是在模型中使用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 
29

阿亚兹对相当多地方,除了有轻微的变化(?):

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中设置小部件字典。

5

如果你试图改变多行文本上admin.py,这是对我工作的解决方案:

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数据库,你的列长度通常会被自动设置到250字符,因此您需要运行ALTER TABLE来更改MySQL DB的长度,以便您可以利用您在Admin Django站点中拥有的新的更大的Textarea。

0

想要扩展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其中titleslug & stateTextField S和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'] 

认为其他人在寻找答案可能会觉得这很有用。