Изменение размера полей в Django Admin
Джанго стремится заполнить горизонтальное пространство при добавлении или редактировании записи в админке, но, в некоторых случаях, это пустая трата пространства, когда, например, редактирования поле даты, 8 символов в ширину, или в страничке, а также 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 и хотел изменить значение по умолчанию для "строк" в связанной текстовой области. 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 при определении модели. Я адаптировал его из ответ на подобный вопрос.
Это хорошо описано в Django 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)
Comments