Изменение размера полей в Django Admin

Django имеет тенденцию заполнять горизонтальное пространство при добавлении или редактировании записей в admin, но в некоторых случаях это настоящая трата пространства, Когда, т. е. редактирование поля даты, шириной 8 символов или CharField, также 6 или 8 символов, а затем поле редактирования доходит до 15 или 20 символов.

Как я могу сказать администратору, насколько широким должно быть текстовое поле или высота поля редактирования текстового поля?

11 ответов


вы должны использовать ModelAdmin.formfield_overrides.

Это довольно легко - в admin.py, определить:

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)

не забывайте, что вы должны импортировать соответствующие классы-в данном случае:

from django.forms import TextInput, Textarea
from django.db import models

вы можете установить произвольные атрибуты HTML на виджете, используя его свойство "attrs".

вы можете сделать это в Администраторе 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}}

быстрый и грязный вариант-просто предоставить пользовательский шаблон для этой модели.

если вы создаете шаблон с именем admin/<app label>/<class name>/change_form.html затем администратор будет использовать этот шаблон вместо шаблона по умолчанию. То есть, если у вас есть модель с названием Person в приложении с именем people, вы создадите шаблон с именем admin/people/person/change_form.html.

все шаблоны администратора есть extrahead блок вы можете переопределить, чтобы поместить материал в <head>, и последняя часть головоломки является тот факт, что каждое поле имеет HTML-код id_<field-name>.

таким образом, вы можете поместить что-то вроде следующего в свой шаблон:

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

{% block extrahead %}
  {{ block.super }}
  <style type="text/css">
    #id_my_field { width: 100px; }
  </style>
{% endblock %}

чтобы изменить ширину для определенного поля.

через 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

Если вы хотите изменить атрибуты экземпляра для каждого поля, вы можете добавить свойство "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)

затем используйте MyTextField вместо TextField при определении вашего модели. Я адаптировал его из ответ на подобный вопрос.


Это хорошо описано в Джанго FAQ:

Q: как изменить атрибуты виджета на поле в моей модели?

A: переопределить formfield_for_dbfield в классе ModelAdmin/StackedInline/TabularInline

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",)}

для 1.6, используя формы, я должен был указать атрибуты textarea внутри charfield:

test1 = forms.CharField(max_length=400, widget=forms.Textarea( attrs={'rows':'2', 'cols': '10'}),  initial='', help_text=helptexts.helptxt['test'])

тот же ответ, что и 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)