mam
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 )
jak przypisać widżet TextArea do pola „descr” w interfejsie administratora?
UPD:
W Admin tylko interfejs!
Dobry pomysł na użycie ModelForm.
django
django-admin
maxp
źródło
źródło
Odpowiedzi:
Będziesz musiał utworzyć,
forms.ModelForm
który będzie opisywał, jak chcesz, abydescr
pole było wyświetlane, a następnie wskaż,admin.ModelAdmin
aby użyć tego formularza. Na przykład: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
Atrybutemadmin.ModelAdmin
jest udokumentowana w oficjalnej dokumentacji Django. Oto jedno miejsce, na które warto spojrzeć .źródło
formfield_for_dbfield
swojąModelAdmin
, zobacz moją odpowiedź poniżej.django.core.exceptions.ImproperlyConfigured: Creating a ModelForm without either the 'fields' attribute or the 'exclude' attribute is prohibited
fields = '__all__'
podclass Meta:
.get_form
metodę. Zobacz moją odpowiedź .W tym przypadku najlepszą opcją jest prawdopodobnie użycie w modelu TextField zamiast CharField. Możesz także nadpisać
formfield_for_dbfield
metodę swojejModelAdmin
klasy: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
źródło
formfield.widget = forms.Textarea()
przez,formfield.widget = forms.Textarea(attrs=formfield.widget.attrs)
aby zachować wszystkie atrybuty generowane automatycznie dla pola tekstowego.super()
. W przeciwnym razie nie.Ayaz ma dość dobre miejsce, z wyjątkiem niewielkiej zmiany (?!):
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)
Nie musisz więc redefiniować pola w ModelForm, aby zmienić jego widżet, po prostu ustaw widżety w Meta.
źródło
Możesz podklasować swoje własne pole wymaganą
formfield
metodą:class CharFieldWithTextarea(models.CharField): def formfield(self, **kwargs): kwargs.update({"widget": forms.Textarea}) return super(CharFieldWithTextarea, self).formfield(**kwargs)
Będzie to miało wpływ na wszystkie wygenerowane formularze.
źródło
Nie musisz samodzielnie tworzyć klasy formularza:
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)
Zobacz ModelAdmin.get_form .
źródło
Zamiast a
models.CharField
użyjmodels.TextField
fordescr
.źródło
Jeśli próbujesz zmienić obszar Textarea na admin.py, to jest rozwiązanie, które działało dla mnie:
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)
Jeśli używasz bazy danych MySQL, długość twojej kolumny będzie zwykle ustawiana automatycznie na 250 znaków, więc będziesz chciał uruchomić ALTER TABLE, aby zmienić długość w swojej bazie danych MySQL, abyś mógł skorzystać z nowego, większego obszaru Textarea, który możesz masz w sobie witrynę Admin Django.
źródło
Możesz użyć
models.TextField
w tym celu:class Sample(models.Model): field1 = models.CharField(max_length=128) field2 = models.TextField(max_length=1024*2) # Will be rendered as textarea
źródło
Chciał rozwinąć odpowiedź Carla Meyera, która do dziś działa doskonale.
Zawsze używam
TextField
zamiastCharField
(z opcjami lub bez) i narzucam limity znaków po stronie interfejsu użytkownika / API, a nie na poziomie bazy danych. Aby to działało dynamicznie: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
Mam nazwę modelu
Post
gdzietitle
,slug
istate
toTextField
s istate
ma wyborów. Definicja administratora wygląda następująco:@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']
Pomyślałem, że inni szukający odpowiedzi mogą uznać to za przydatne.
źródło
formfield_for_dbfield
udokumentowane?