Redimensionner les champs dans Django Admin
Django a tendance à remplir l'espace horizontal lors de l'ajout ou de l'édition d'entrées sur l'administrateur, mais, dans certains cas, est un véritable gaspillage d'espace, lorsque, c'est-à-dire, éditer un champ de date, 8 caractères de large, ou un CharField, aussi 6 ou 8 caractères de large, puis la zone d'édition va jusqu'à 15 ou 20 caractères.
Comment puis-je indiquer à l'administrateur la largeur d'une zone de texte ou la hauteur d'une zone D'édition de champ de texte?
11 réponses
, Vous devez utiliser ModelAdmin.formfield_overrides.
C'est assez facile-dans admin.py
, Définissez:
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)
N'oubliez pas que vous devez importer les classes appropriées, dans ce cas:
from django.forms import TextInput, Textarea
from django.db import models
Vous pouvez définir des attributs HTML arbitraires sur un widget en utilisant sa propriété "attrs" .
Vous pouvez le faire dans L'administrateur Django en utilisant 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
Ou avec une sous-classe de Widget personnalisée et le dictionnaire 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}}
Une option rapide et sale consiste simplement à fournir un modèle personnalisé pour le modèle en question.
Si vous créez un modèle nommé admin/<app label>/<class name>/change_form.html
, l'administrateur utilisera ce modèle au lieu du modèle par défaut. C'est, si vous avez un modèle nommé Person
dans une application nommée people
, vous devez créer un modèle nommé admin/people/person/change_form.html
.
Tous les modèles d'administration ont un bloc extrahead
que vous pouvez remplacer pour placer des éléments dans le <head>
, et la dernière pièce du puzzle est le fait que chaque champ a un identifiant HTML de id_<field-name>
.
Donc, vous pouvez mettre quelque chose comme ce qui suit dans votre modèle:
{% extends "admin/change_form.html" %}
{% block extrahead %}
{{ block.super }}
<style type="text/css">
#id_my_field { width: 100px; }
</style>
{% endblock %}
Pour modifier la largeur d'un champ spécifique.
Fait via 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
Si vous souhaitez modifier les attributs sur une instance par champ, vous pouvez ajouter la propriété" attrs " directement dans vos entrées de formulaire.
Par exemple:
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')
La propriété" attrs " passe essentiellement le long du balisage HTML qui ajustera le champ de formulaire. Chaque entrée est un n-uplet de l'attribut que vous souhaitez remplacer et de la valeur que vous souhaitez la remplacer par. Vous pouvez entrer autant d'attributs que vous le souhaitez tant que vous séparez chaque tuple avec une virgule.
La meilleure façon que j'ai trouvée est quelque chose comme ceci:
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
C'est beaucoup mieux pour ModelForm que de surcharger les champs avec des widgets différents, car il préserve les attributs name
et help_text
ainsi que les valeurs par défaut des champs de modèle, vous n'avez donc pas besoin de les copier dans votre formulaire.
J'ai eu un problème similaire avec TextField. J'utilise Django 1.0.2 et je voulais changer la valeur par défaut pour 'rows' dans la zone de texte associée. formfield_overrides n'existe pas dans cette version. La substitution de formfield_for_dbfield a fonctionné mais je devais le faire pour chacune de mes sous-classes ModelAdmin ou cela entraînerait une erreur de récursivité. Finalement, j'ai trouvé que l'ajout du code ci-dessous à models.py travaux:
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)
Ensuite, utilisez MyTextField au lieu de TextField lors de la définition de vos modèles. Je adapté de cette réponse à une question similaire.
C'est bien décrit dans Django FAQ :
Q: Comment modifier les attributs d'un widget sur un champ de mon modèle?
A: remplace le champ formfield_for_dbfield dans la classe 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)
Vous pouvez toujours définir la taille de vos champs dans une feuille de style personnalisée et dire à Django de l'utiliser pour votre classe ModelAdmin:
class MyModelAdmin(ModelAdmin):
class Media:
css = {"all": ("my_stylesheet.css",)}
Pour 1.6, en utilisant des formulaires, je devais spécifier les attributs de la zone de texte à l'intérieur du charfield:
test1 = forms.CharField(max_length=400, widget=forms.Textarea( attrs={'rows':'2', 'cols': '10'}), initial='', help_text=helptexts.helptxt['test'])
Même réponse que msdin mais avec TextInput au lieu de 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)