2009-01-10 82 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'] 

認爲其他人在尋找答案可能會覺得這很有用。