eu tenho
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 )
como atribuir widget TextArea ao campo 'descr' na interface de administração?
upd: Somente
na interface Admin !
Boa ideia para usar ModelForm.
django
django-admin
maxp
fonte
fonte
Respostas:
Você terá que criar um
forms.ModelForm
que descreva como deseja que odescr
campo seja exibido e, em seguida, digaadmin.ModelAdmin
para usar esse formulário. Por exemplo: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
O
form
atributo deadmin.ModelAdmin
está documentado na documentação oficial do Django. Aqui está um lugar para olhar .fonte
formfield_for_dbfield
no seuModelAdmin
, veja minha resposta abaixo.django.core.exceptions.ImproperlyConfigured: Creating a ModelForm without either the 'fields' attribute or the 'exclude' attribute is prohibited
fields = '__all__'
emclass Meta:
.get_form
método. Veja minha resposta .Para este caso, a melhor opção provavelmente é apenas usar um TextField em vez de CharField em seu modelo. Você também pode substituir o
formfield_for_dbfield
método de suaModelAdmin
classe: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
fonte
formfield.widget = forms.Textarea()
porformfield.widget = forms.Textarea(attrs=formfield.widget.attrs)
para manter todos os atributos gerados automaticamente para o TextField, obrigado!super()
. Caso contrário, não.Ayaz acertou em cheio, exceto por uma ligeira mudança (?!):
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)
Portanto, você não precisa redefinir um campo no ModelForm para alterar seu widget, apenas defina o dict dos widgets no Meta.
fonte
Você pode criar uma subclasse de seu próprio campo com o
formfield
método necessário :class CharFieldWithTextarea(models.CharField): def formfield(self, **kwargs): kwargs.update({"widget": forms.Textarea}) return super(CharFieldWithTextarea, self).formfield(**kwargs)
Isso terá efeito em todos os formulários gerados.
fonte
Você não precisa criar a classe de formulário sozinho:
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)
Consulte ModelAdmin.get_form .
fonte
Se você está tentando alterar a Textarea em admin.py, esta é a solução que funcionou para mim:
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)
Se você estiver usando um banco de dados MySQL, o comprimento da coluna geralmente será definido automaticamente para 250 caracteres, então você vai querer executar um ALTER TABLE para alterar o comprimento em seu banco de dados MySQL, para que você possa aproveitar a nova Textarea maior que você tem em seu site Admin Django.
fonte
Em vez de um
models.CharField
, use ummodels.TextField
fordescr
.fonte
Você pode usar
models.TextField
para esta finalidade:class Sample(models.Model): field1 = models.CharField(max_length=128) field2 = models.TextField(max_length=1024*2) # Will be rendered as textarea
fonte
Queria expandir a resposta de Carl Meyer, que funciona perfeitamente até hoje.
Eu sempre uso em
TextField
vez deCharField
(com ou sem opções) e imponho limites de caracteres no lado da interface do usuário / API em vez de no nível do banco de dados. Para fazer isso funcionar de forma dinâmica: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
Eu tenho um nome do modelo
Post
, ondetitle
,slug
estate
sãoTextField
s estate
tem escolhas. A definição do administrador se parece com:@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']
Achei que outras pessoas em busca de respostas poderiam achar isso útil.
fonte
formfield_for_dbfield
documentado?