у меня есть
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.
django
django-admin
maxp
источник
источник
Ответы:
Вам нужно будет создать форму,
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. Вот одно место, на которое можно посмотреть .источник
formfield_for_dbfield
свойModelAdmin
, см. Мой ответ ниже.django.core.exceptions.ImproperlyConfigured: Creating a ModelForm without either the 'fields' attribute or the 'exclude' attribute is prohibited
fields = '__all__'
подclass Meta:
.get_form
метод. Смотрите мой ответ .В этом случае лучшим вариантом, вероятно, будет просто использовать 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
источник
formfield.widget = forms.Textarea()
с ,formfield.widget = forms.Textarea(attrs=formfield.widget.attrs)
чтобы сохранить все атрибуты автоматически сгенерированные для TextField, спасибо!super()
. В противном случае нет.Аяз в значительной степени подходит, за исключением небольшого изменения (?!):
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.
источник
Вы можете подклассифицировать собственное поле с помощью необходимого
formfield
метода:class CharFieldWithTextarea(models.CharField): def formfield(self, **kwargs): kwargs.update({"widget": forms.Textarea}) return super(CharFieldWithTextarea, self).formfield(**kwargs)
Это повлияет на все сгенерированные формы.
источник
Самостоятельно создавать класс формы не нужно:
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 .
источник
Если вы пытаетесь изменить 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, чтобы изменить длину в вашей базе данных MySQL, чтобы вы могли воспользоваться преимуществами нового большего Textarea, которое вы есть у вас админский сайт Django.
источник
Вместо a
models.CharField
используйтеmodels.TextField
fordescr
.источник
models.TextField
Для этого можно использовать :class Sample(models.Model): field1 = models.CharField(max_length=128) field2 = models.TextField(max_length=1024*2) # Will be rendered as textarea
источник
Хотел расширить ответ Карла Мейера, который отлично работает до сих пор.
Я всегда использую
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
и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']
Подумал, что другие, ищущие ответы, могут найти это полезным.
источник
formfield_for_dbfield
задокументировано?