调整Django Admin中的字段大小

And*_*dor 103 python django django-models django-admin

当在管理员上添加或编辑条目时,Django往往会填满水平空间,但在某些情况下,真正浪费空间,即编辑日期字段,8个字符宽,或CharField,也是6或8 chars wide,然后编辑框上升到15或20个字符.

如何告诉管理员文本框应该有多宽,或者TextField编辑框的高度?

jki*_*jki 199

您应该使用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)
Run Code Online (Sandbox Code Playgroud)

不要忘记你应该导入适当的类 - 在这种情况下:

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)
Run Code Online (Sandbox Code Playgroud)

  • 请注意,如果为 YourModelAdmin 中的相应字段设置了 `filter_horizo​​ntal` 或 `filter_vertical`,这将不起作用。我花了一些时间来弄清楚这一点。 (2认同)

Car*_*yer 45

您可以使用其"attrs"属性在窗口小部件上设置任意HTML属性.

您可以使用formfield_for_dbfield在Django管理员中执行此操作:

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
Run Code Online (Sandbox Code Playgroud)

或者使用自定义Widget子类和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}}
Run Code Online (Sandbox Code Playgroud)


ala*_*jds 27

更改特定字段的宽度.

通过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
Run Code Online (Sandbox Code Playgroud)


jac*_*ian 21

一个快速而肮脏的选择是简单地为相关模型提供自定义模板.

如果您创建了一个名为的模板,admin/<app label>/<class name>/change_form.html那么管理员将使用该模板而不是默认模板.也就是说,如果您在名为Personapp的应用程序中找到了一个模型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 %}
Run Code Online (Sandbox Code Playgroud)


小智 10

如果要更改每个字段实例的属性,可以将"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')
Run Code Online (Sandbox Code Playgroud)

"attrs"属性基本上传递HTML标记,该标记将调整表单字段.每个条目都是您要覆盖的属性的元组以及您要覆盖它的值.只要用逗号分隔每个元组,就可以输入任意数量的属性.


kur*_*zak 7

我找到的最好的方法是这样的:

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
Run Code Online (Sandbox Code Playgroud)

它为很多比的ModelForm覆盖不同部件领域,因为它保留了更好的namehelp_text属性,也默认模型字段的值,所以您不必将它们复制到您的形式.


小智 7

我在TextField上遇到了类似的问题.我正在使用Django 1.0.2,并希望更改相关textarea中'rows'的默认值.此版本中不存在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)
Run Code Online (Sandbox Code Playgroud)

然后在定义模型时使用MyTextField而不是TextField.我从这个问题的答案中改编了它.


Har*_*ons 5

它在Django FAQ中有详细描述:

问:如何在模型中的字段上更改窗口小部件的属性?

答:覆盖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)
Run Code Online (Sandbox Code Playgroud)


Gon*_*alo 5

您始终可以在自定义样式表中设置字段大小,并告诉Django将其用于您的ModelAdmin类:

class MyModelAdmin(ModelAdmin):
    class Media:
        css = {"all": ("my_stylesheet.css",)}
Run Code Online (Sandbox Code Playgroud)