Django-Admin: CharField как TextArea
У меня
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:
В интерфейсе Admin!
Хорошая идея использовать ModelForm.
Ответы
Ответ 1
Вам нужно будет создать 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. Вот одно место для просмотра.
Ответ 2
В этом случае лучшим вариантом является, вероятно, просто использование 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
Ответ 3
Аяз имеет довольно много места, кроме небольшого изменения (?!):
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, чтобы изменить его виджет, просто установите виджеты dict в Meta.
Ответ 4
Вы можете formfield
подкласс для своего собственного поля с помощью необходимого метода formfield
:
class CharFieldWithTextarea(models.CharField):
def formfield(self, **kwargs):
kwargs.update({"widget": forms.Textarea})
return super(CharFieldWithTextarea, self).formfield(**kwargs)
Это повлияет на все сгенерированные формы.
Ответ 5
Если вы пытаетесь изменить Textarea на 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, чтобы изменить длину в вашем DB DB, чтобы вы могли использовать новые более крупные Textarea, что у вас есть у вас сайт Admin Django.
Ответ 6
Вам не нужно создавать класс формы самостоятельно:
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
Вместо models.CharField
используйте models.TextField
для descr
.
Ответ 8
Требуется расширить ответ на вопрос Карла Мейера, который отлично работает до этой даты.
Я всегда использую TextField
вместо CharField
(с или без выбора) и накладываю ограничения символов на стороне интерфейса /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
и state
есть 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']
Мысль, что другие, ищущие ответы, могут найти это полезным.
Ответ 9
Вы можете использовать models.TextField
для этой цели:
class Sample(models.Model):
field1 = models.CharField(max_length=128)
field2 = models.TextField(max_length=1024*2) # Will be rendered as textarea