Django-Admin : CharField as TextArea


87

나는 가지고있다

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 )

관리자 인터페이스의 'descr'필드에 TextArea 위젯을 할당하는 방법은 무엇입니까?

UPD :
에서 관리자 인터페이스 만!

ModelForm을 사용하는 것이 좋습니다.


3
허용되는 대답은 하나의 필드 만 수정하기위한 엄청난 과잉입니다! 사람들은
단순성을

답변:


99

당신은 만들어야합니다 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 문서에 문서화되어 있습니다. 여기 에 살펴볼 곳이 있습니다.


6
단순히 양식 위젯을 교체하기 위해 전체 양식을 만들 필요가 없습니다. 당신은 대체 할 수 있습니다 formfield_for_dbfield당신에 ModelAdmin, 내 대답은 아래를 참조하십시오.
Carl Meyer

1
이것은 제공합니다django.core.exceptions.ImproperlyConfigured: Creating a ModelForm without either the 'fields' attribute or the 'exclude' attribute is prohibited
John Wu

4
장고 1.7에서 시작 당신은 또한 추가 할 필요가 fields = '__all__'에서 class Meta:.
skoll

2
양식을 직접 만들 필요는 없으며 get_form메서드 를 재정의 할 수 있습니다 . 내 대답을 참조하십시오 .
x-yuri

모델 = 메시지 위젯 = { '텍스트': forms.Textarea (바인드합니다 = { 'COLS'80, '행': 20})} beeter 접근 방식은 사용하는 메타 클래스 메타입니다
아물 야 아차

58

이 경우 가장 좋은 옵션은 모델에서 CharField 대신 TextField를 사용하는 것입니다. 클래스 의 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

선택한 답변과 비교할 때 단점이 있습니까? 우리는 새로운 ModelForm를 만들 필요가 없기 때문에이 보이는 청소기 ... 구현
필리페 피나에게

3
교체 formfield.widget = forms.Textarea()formfield.widget = forms.Textarea(attrs=formfield.widget.attrs), 감사를 자동으로 텍스트 필드에 대해 생성 된 모든 속성을 유지하기!
Filipe Pina 2012

2
이 질문에 대해 다른 답변이 허용되는 이유를 모르겠습니다. 나는 당신이하고있는 모든 것이 위젯을 교체하는 것이라면 이것이 더 간단하다고 생각합니다. 그러나 둘 다 잘 작동합니다.
Carl Meyer

이것은 완벽하게 작동했습니다. 감사합니다. super () 호출은 약간 장황 해 보이지만 더 간단한 방법이 있습니까?
rjh

2
@rjh py3에서는 괄호 안의 모든 것을 제거하고 super(). 그렇지 않으면 아닙니다.
Carl Meyer

32

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에서 위젯 사전을 설정하기 만하면됩니다.


1
이것은 Ayaz의 대답보다 더 많은 "자동"속성을 유지하지만 필드 길이 유효성 검사를 유지하는 방법에 대한 팁이 있습니까?
Filipe Pina 2012

14

필요한 formfield메서드로 자신의 필드를 하위 클래스로 만들 수 있습니다 .

class CharFieldWithTextarea(models.CharField):

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

이것은 생성 된 모든 양식에 적용됩니다.


9

양식 클래스를 직접 만들 필요는 없습니다.

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을 참조하십시오 .


7

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 사이트에 있습니다.


6

대신에 for를 models.CharField사용하십시오 .models.TextFielddescr


4
불행히도 max_length =는 TextField에서 Django에 의해 완전히 무시되므로 필드 길이 유효성 검사가 필요할 때 (비서가 이벤트 요약을 입력하도록하는 것과 같은) 유일한 방법은 CharField를 사용하는 것입니다. 그러나 CharField는 300자를 짧게 입력하는 방법입니다. 따라서 ayaz 솔루션.
shacker

3
이것은 데이터베이스를 변경하기 때문에 좋은 대답이 아닙니다. 위젯 변경의 요점은 데이터베이스 스키마를 변경하는 것이 아니라 필드 표시 방식을 변경하는 것입니다.

1
Django 사용법을 배우고 있고 내가 더 잘 알고 있었다면 처음에 데이터베이스를 다르게 설정했을 사람 (나와 같은)에게 훌륭한 대답입니다.
Andrew Swift

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

3
이 있으므로주의 해 DB 구조 변경됩니다
elad은

3

현재까지 완벽하게 작동하는 Carl Meyer의 답변을 확장하고 싶었습니다.

나는 항상 (선택의 유무에 관계없이) TextField대신 사용 CharField하고 DB 수준이 아닌 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, slugstate있습니다 TextField들과 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']

답을 찾는 다른 사람들이 이것이 유용하다고 생각했습니다.


이다 formfield_for_dbfield문서화?
x-yuri
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.