Djangoは、管理者でエントリを追加または編集するときに水平方向のスペースを埋める傾向がありますが、場合によっては、日付フィールド、8文字幅、またはCharField、6または8文字幅で、編集ボックスが15または20文字になります。
テキストボックスの幅や、TextField編集ボックスの高さを管理者に伝えるにはどうすればよいですか?
ModelAdmin.formfield_overrides を使用する必要があります。
それは非常に簡単です-admin.py
、定義:
from Django.forms import TextInput, Textarea
from Django.db import models
class YourModelAdmin(admin.ModelAdmin):
formfield_overrides = {
models.CharField: {'widget': TextInput(attrs={'size':'20'})},
models.TextField: {'widget': Textarea(attrs={'rows':4, 'cols':40})},
}
admin.site.register(YourModel, YourModelAdmin)
"attrs"プロパティ を使用して、ウィジェットに任意のHTML属性を設定できます。
これを行うには、Django adminでformfield_for_dbfieldを使用します。
class MyModelAdmin(admin.ModelAdmin):
def formfield_for_dbfield(self, db_field, **kwargs):
field = super(ContentAdmin, self).formfield_for_dbfield(db_field, **kwargs)
if db_field.name == 'somefield':
field.widget.attrs['class'] = 'someclass ' + field.widget.attrs.get('class', '')
return field
または、カスタムウィジェットサブクラスと formfield_overrides辞書 :
class DifferentlySizedTextarea(forms.Textarea):
def __init__(self, *args, **kwargs):
attrs = kwargs.setdefault('attrs', {})
attrs.setdefault('cols', 80)
attrs.setdefault('rows', 5)
super(DifferentlySizedTextarea, self).__init__(*args, **kwargs)
class MyModelAdmin(admin.ModelAdmin):
formfield_overrides = { models.TextField: {'widget': DifferentlySizedTextarea}}
特定のフィールドの幅を変更するには
ModelAdmin.get_form で作成:
class YourModelAdmin(admin.ModelAdmin):
def get_form(self, request, obj=None, **kwargs):
form = super(YourModelAdmin, self).get_form(request, obj, **kwargs)
form.base_fields['myfield'].widget.attrs['style'] = 'width: 45em;'
return form
迅速で汚いオプションは、問題のモデルにカスタムテンプレートを単に提供することです。
admin/<app label>/<class name>/change_form.html
という名前のテンプレートを作成すると、管理者はデフォルトではなくそのテンプレートを使用します。つまり、Person
という名前のアプリにpeople
という名前のモデルがある場合、admin/people/person/change_form.html
という名前のテンプレートを作成します。
すべての管理テンプレートにはextrahead
ブロックがあり、オーバーライドして<head>
にデータを配置できます。パズルの最後のピースは、すべてのフィールドのHTML IDがid_<field-name>
であるという事実です。 。
そのため、次のようなものをテンプレートに入れることができます。
{% extends "admin/change_form.html" %}
{% block extrahead %}
{{ block.super }}
<style type="text/css">
#id_my_field { width: 100px; }
</style>
{% endblock %}
フィールドごとのインスタンスの属性を変更する場合は、フォームエントリに「attrs」プロパティを直接追加できます。
例えば:
class BlogPostForm(forms.ModelForm):
title = forms.CharField(label='Title:', max_length=128)
body = forms.CharField(label='Post:', max_length=2000,
widget=forms.Textarea(attrs={'rows':'5', 'cols': '5'}))
class Meta:
model = BlogPost
fields = ('title', 'body')
「attrs」プロパティは基本的に、フォームフィールドを調整するHTMLマークアップに沿って渡されます。各エントリは、オーバーライドする属性とオーバーライドする値のタプルです。各タプルをコンマで区切る限り、好きなだけ属性を入力できます。
私が見つけた最良の方法は次のようなものです:
class NotificationForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
super(NotificationForm, self).__init__(*args, **kwargs)
self.fields['content'].widget.attrs['cols'] = 80
self.fields['content'].widget.attrs['rows'] = 15
self.fields['title'].widget.attrs['size'] = 50
class Meta:
model = Notification
name
およびhelp_text
属性とモデルフィールドのデフォルト値を保持するため、異なるウィジェットでフィールドをオーバーライドするよりもModelFormの方がはるかに優れているため、フォームにコピーする必要はありません。
TextFieldでも同様の問題がありました。 Django 1.0.2を使用しており、関連するtextareaの 'rows'のデフォルト値を変更したかったです。このバージョンではformfield_overridesは存在しません。 ModelAdminサブクラスごとにそれを使用しないと、再帰エラーが発生することになります。
from Django.forms import Textarea
class MyTextField(models.TextField):
#A more reasonably sized textarea
def formfield(self, **kwargs):
kwargs.update(
{"widget": Textarea(attrs={'rows':2, 'cols':80})}
)
return super(MyTextField, self).formfield(**kwargs)
次に、モデルを定義するときに、TextFieldではなくMyTextFieldを使用します。 this answer から同様の質問に変更しました。
常にカスタムスタイルシートでフィールドサイズを設定し、ModelAdminクラスで使用するようにDjangoに伝えることができます。
class MyModelAdmin(ModelAdmin):
class Media:
css = {"all": ("my_stylesheet.css",)}
Django FAQ で詳しく説明されています:
Q:モデルのフィールド上のウィジェットの属性を変更するにはどうすればよいですか?
A:ModelAdmin/StackedInline/TabularInlineクラスのformfield_for_dbfieldをオーバーライドします
class MyOtherModelInline(admin.StackedInline):
model = MyOtherModel
extra = 1
def formfield_for_dbfield(self, db_field, **kwargs):
# This method will turn all TextFields into giant TextFields
if isinstance(db_field, models.TextField):
return forms.CharField(widget=forms.Textarea(attrs={'cols': 130, 'rows':30, 'class': 'docx'}))
return super(MyOtherModelInline, self).formfield_for_dbfield(db_field, **kwargs)
1.6では、フォームを使用して、charfield内のtextareaの属性を指定する必要がありました。
test1 = forms.CharField(max_length=400, widget=forms.Textarea( attrs={'rows':'2', 'cols': '10'}), initial='', help_text=helptexts.helptxt['test'])
Msdinと同じ答えですが、TextAreaの代わりにTextInputを使用します。
from Django.forms import TextInput
class ShortTextField(models.TextField):
def formfield(self, **kwargs):
kwargs.update(
{"widget": TextInput(attrs={'size': 10})}
)
return super(ShortTextField, self).formfield(**kwargs)
そしてもう1つの例:
class SecenekInline(admin.TabularInline):
model = Secenek
# classes = ['collapse']
def formfield_for_dbfield(self, db_field, **kwargs):
field = super(SecenekInline, self).formfield_for_dbfield(db_field, **kwargs)
if db_field.name == 'harf':
field.widget = TextInput(attrs={'size':2})
return field
formfield_overrides = {
models.TextField: {'widget': Textarea(attrs={'rows':2})},
}
extra = 2
特定のフィールドサイズのみを編集する場合は、これを使用できます。
選択肢/オプション/ドロップダウンメニューを含むForeignKeyフィールドで作業している場合は、formfield_for_foreignkey
Adminインスタンス内:
class YourNewAdmin(admin.ModelAdmin):
...
def formfield_for_foreignkey(self, db_field, request, **kwargs):
if db_field.name == 'your_fk_field':
""" For your FK field of choice, override the dropdown style """
kwargs["widget"] = Django.forms.widgets.Select(attrs={
'style': 'width: 250px;'
})
return super().formfield_for_foreignkey(db_field, request, **kwargs)
以下は、シンプルでありながら柔軟なソリューションです。カスタムフォームを使用して、一部のウィジェットをオーバーライドします。
# models.py
class Elephant(models.Model):
name = models.CharField(max_length=25)
age = models.IntegerField()
# forms.py
class ElephantForm(forms.ModelForm):
class Meta:
widgets = {
'age': forms.TextInput(attrs={'size': 3}),
}
# admin.py
@admin.register(Elephant)
class ElephantAdmin(admin.ModelAdmin):
form = ElephantForm
ElephantForm
で指定されたウィジェットは、デフォルトのものを置き換えます。キーは、フィールドの文字列表現です。フォームで指定されていないフィールドは、デフォルトのウィジェットを使用します。
age
はIntegerField
ですが、TextInput
とは異なり、NumberInput
はTextInput
属性を受け入れるため、size
ウィジェットを使用できます。
このソリューションは この記事 で説明されています。