121

Django 在管理员上添加或编辑条目时往往会填满水平空间,但在某些情况下,当编辑一个 8 个字符宽的日期字段或一个同样为 6 或 8 个字符的字段时,这是一种真正的空间浪费字符宽,然后编辑框增加到 15 或 20 个字符。

如何告诉管理员文本框的宽度或 TextField 编辑框的高度?

4

14 回答 14

241

您应该使用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)
于 2009-11-16T19:24:46.610 回答
45

您可以使用小部件的“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

或使用自定义 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}}
于 2009-05-26T17:57:49.063 回答
34

更改特定字段的宽度。

通过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
于 2014-02-13T21:56:18.820 回答
22

一个快速而肮脏的选择是简单地为有问题的模型提供一个自定义模板。

如果您创建一个名为的模板admin/<app label>/<class name>/change_form.html,那么管理员将使用该模板而不是默认模板。也就是说,如果您有一个名为Person的应用程序中的模型people,您将创建一个名为 的模板admin/people/person/change_form.html

所有管理模板都有一个extrahead块,您可以覆盖以<head>id_<field-name>.

因此,您可以在模板中添加以下内容:

{% extends "admin/change_form.html" %}

{% block extrahead %}
  {{ block.super }}
  <style type="text/css">
    #id_my_field { width: 100px; }
  </style>
{% endblock %}
于 2009-05-26T20:45:00.973 回答
11

如果要更改每个字段实例的属性,可以将“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 标记。每个条目都是您想要覆盖的属性和您想要覆盖它的值的元组。只要用逗号分隔每个元组,就可以输入任意数量的属性。

于 2009-05-27T01:36:50.417 回答
8

我发现的最好方法是这样的:

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 来说,它比使用不同的小部件覆盖字段要好得多,因为它保留了属性namehelp_text模型字段的默认值,因此您不必将它们复制到表单中。

于 2009-08-09T17:58:57.723 回答
8

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

class MyModelAdmin(ModelAdmin):
    class Media:
        css = {"all": ("my_stylesheet.css",)}
于 2010-01-26T09:11:02.200 回答
7

我对 TextField 有类似的问题。我正在使用 Django 1.0.2 并想更改关联文本区域中“行”的默认值。此版本中不存在 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)

然后在定义模型时使用 MyTextField 而不是 TextField。我将它从这个答案改编为类似的问题。

于 2010-01-26T02:48:20.093 回答
5

Django FAQ中有很好的描述:

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

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)
于 2009-09-02T15:02:06.667 回答
2

对于 1.6,使用表单我必须在 charfield 内指定 textarea 的属性:

test1 = forms.CharField(max_length=400, widget=forms.Textarea( attrs={'rows':'2', 'cols': '10'}),  initial='', help_text=helptexts.helptxt['test'])
于 2013-03-27T02:10:18.593 回答
2

这是一个简单但灵活的解决方案。使用自定义表单来覆盖一些小部件。

# 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小部件,因为与 , 不同NumberInputTextInput接受size属性。

此解决方案在本文中进行了描述。

于 2019-01-29T09:44:15.203 回答
1

与 msdin 相同的答案,但使用 TextInput 而不是 TextArea:

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)
于 2011-12-18T15:04:13.820 回答
0

如果您正在使用涉及选项/选项/下拉菜单的 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)

有关此模式的更多信息,请点击此处此处

于 2019-03-28T18:27:26.137 回答
-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

如果您只想编辑特定的字段大小,可以使用它。

于 2019-05-09T10:24:58.180 回答