Djangoは、adminでエントリを追加または編集するときに水平方向のスペースを埋める傾向がありますが、場合によっては、日付フィールド、幅8文字、またはCharField(6または8)を編集するときに、スペースを無駄にすることがあります文字幅が広い場合、編集ボックスは最大15文字または20文字になります。
テキストボックスの幅、またはテキストフィールド編集ボックスの高さを管理者に伝えるにはどうすればよいですか?
Djangoは、adminでエントリを追加または編集するときに水平方向のスペースを埋める傾向がありますが、場合によっては、日付フィールド、幅8文字、またはCharField(6または8)を編集するときに、スペースを無駄にすることがあります文字幅が広い場合、編集ボックスは最大15文字または20文字になります。
テキストボックスの幅、またはテキストフィールド編集ボックスの高さを管理者に伝えるにはどうすればよいですか?
回答:
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)
filter_horizontal
かfilter_vertical
YourModelAdminの対応するフィールドのために設定されています。私はこれを理解するのに少し時間を費やしました。
models.TextField: {'widget': Textarea(attrs={'rows':4})}
が幅も狭くなりました。
「attrs」プロパティを使用して、ウィジェットに任意のHTML属性を設定できます。
これは、Django管理で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
そのそれは保存して、より良いのModelFormに異なるウィジェットでフィールドを上書きするよりもはるかにname
及びhelp_text
属性と、モデルフィールドのデフォルト値は、あなたのフォームにコピーする必要はありませんので。
TextFieldにも同様の問題がありました。私はDjango 1.0.2を使用しており、関連するtextareaの「行」のデフォルト値を変更したいと考えています。formfield_overridesはこのバージョンには存在しません。formfield_for_dbfieldのオーバーライドは機能しましたが、ModelAdminサブクラスごとに行う必要がありました。そうしないと、再帰エラーが発生しました。最終的に、以下のコードをmodels.pyに追加すると機能することがわかりました。
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を使用します。私はこの答えからそれを同様の質問に適応させました。
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)
いつでもカスタムスタイルシートでフィールドサイズを設定し、DjangoにそれをModelAdminクラスに使用するように指示できます。
class MyModelAdmin(ModelAdmin):
class Media:
css = {"all": ("my_stylesheet.css",)}
シンプルでありながら柔軟なソリューションを次に示します。カスタムフォームを使用して一部のウィジェットをオーバーライドします。
# 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
属性を。
選択肢/オプション/ドロップダウンメニューを含むForeignKeyフィールドを使用formfield_for_foreignkey
している場合は、管理インスタンスでオーバーライドできます。
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)
このパターンの詳細については、こちらとこちらをご覧ください。
そしてもう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
特定のフィールドサイズのみを編集する場合は、これを使用できます。