258π
You should use ModelAdmin.formfield_overrides.
It is quite easy β in admin.py
, define:
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)
45π
You can set arbitrary HTML attributes on a widget using its βattrsβ property.
You can do this in the Django admin using 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
or with a custom Widget subclass and the formfield_overrides dictionary:
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}}
- [Django]-Where is a good place to work on accounts/profile in Django with the Django registration app?
- [Django]-How to duplicate virtualenv
- [Django]-Sending post data from angularjs to django as JSON and not as raw content
44π
To change the width for a specific field.
Made 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
- [Django]-Django ignores router when running tests?
- [Django]-Adding a user to a group in django
- [Django]-Django Multiple Authentication Backend for one project
24π
A quick and dirty option is to simply provide a custom template for the model in question.
If you create a template named admin/<app label>/<class name>/change_form.html
then the admin will use that template instead of the default. That is, if youβve got a model named Person
in an app named people
, youβd create a template named admin/people/person/change_form.html
.
All the admin templates have an extrahead
block you can override to place stuff in the <head>
, and the final piece of the puzzle is the fact that every field has an HTML id of id_<field-name>
.
So, you could put something like the following in your template:
{% extends "admin/change_form.html" %}
{% block extrahead %}
{{ block.super }}
<style type="text/css">
#id_my_field { width: 100px; }
</style>
{% endblock %}
- [Django]-Django Reverse with arguments '()' and keyword arguments '{}' not found
- [Django]-How to get a favicon to show up in my django app?
- [Django]-Django.db.migrations.exceptions.InconsistentMigrationHistory
11π
If you want to change the attributes on a per-field instance, you can add the βattrsβ property directly in to your form entries.
for example:
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')
The βattrsβ property basically passes along the HTML markup that will adjust the form field. Each entry is a tuple of the attribute you would like to override and the value you would like to override it with. You can enter as many attributes as you like as long as you separate each tuple with a comma.
- [Django]-What's the best solution for OpenID with Django?
- [Django]-Django celery task: Newly created model DoesNotExist
- [Django]-You need to install postgresql-server-dev-X.Y for building a server-side extension or libpq-dev for building a client-side application
8π
The best way I found is something like this:
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
Its much better for ModelForm than overriding fields with different widgets, as it preserves name
and help_text
attributes and also default values of model fields, so you donβt have to copy them to your form.
- [Django]-How to display the current year in a Django template?
- [Django]-Django FileField with upload_to determined at runtime
- [Django]-Negating a boolean in Django template
8π
You can always set your fields sizes in a custom stylesheet and tell Django to use that for your ModelAdmin class:
class MyModelAdmin(ModelAdmin):
class Media:
css = {"all": ("my_stylesheet.css",)}
- [Django]-Django: Filter a Queryset made of unions not working
- [Django]-Django rest framework: query parameters in detail_route
- [Django]-Django REST framework: non-model serializer
7π
I had a similar problem with TextField. Iβm using Django 1.0.2 and wanted to change the default value for βrowsβ in the associated textarea. formfield_overrides doesnβt exist in this version. Overriding formfield_for_dbfield worked but I had to do it for each of my ModelAdmin subclasses or it would result in a recursion error. Eventually, I found that adding the code below to models.py works:
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)
Then use MyTextField instead of TextField when defining your models. I adapted it from this answer to a similar question.
- [Django]-Can I access constants in settings.py from templates in Django?
- [Django]-Django: How to manage development and production settings?
- [Django]-Migrating Django fixtures?
5π
Itβs well described in Django FAQ:
Q: How do I change the attributes for a widget on a field in my model?
A: Override the formfield_for_dbfield in the ModelAdmin/StackedInline/TabularInline class
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]-How can I get the full/absolute URL (with domain) in Django?
- [Django]-Disabled field is not passed through β workaround needed
- [Django]-Django: Display Choice Value
2π
for 1.6, using forms I had to specify the attributes of the textarea inside the charfield:
test1 = forms.CharField(max_length=400, widget=forms.Textarea( attrs={'rows':'2', 'cols': '10'}), initial='', help_text=helptexts.helptxt['test'])
- [Django]-Form with CheckboxSelectMultiple doesn't validate
- [Django]-How to compare two JSON objects with the same elements in a different order equal?
- [Django]-Django gives Bad Request (400) when DEBUG = False
2π
Here is a simple, yet flexible solution. Use a custom form to override some widgets.
# 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
The widgets given in ElephantForm
will replace the default ones. The key is the string representation of the field. Fields not specified in the form will use the default widget.
Note that although age
is an IntegerField
we can use the TextInput
widget, because unlike the NumberInput
, TextInput
accepts the size
attribute.
This solution is described in this article.
- [Django]-How to define two fields "unique" as couple
- [Django]-Do I need Nginx with Gunicorn if I am not serving any static content?
- [Django]-How to do SELECT COUNT(*) GROUP BY and ORDER BY in Django?
1π
Same answer as msdin but with TextInput instead of 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)
- [Django]-Django {% if forloop.first %} question
- [Django]-Set Django IntegerField by choices=β¦ name
- [Django]-Django override save for model only in some cases?
0π
If you are working with a ForeignKey field that involves choices/options/a dropdown menu, you can override formfield_for_foreignkey
in the Admin instance:
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)
- [Django]-How to set and get cookies in Django?
- [Django]-Django rest framework change primary key to use a unqiue field
- [Django]-Redirect to Next after login in Django
0π
For example, there is Product
model below:
class Product(models.Model):
name = models.CharField(max_length=50)
description = models.TextField()
price = models.DecimalField(decimal_places=2, max_digits=5)
quantity = models.PositiveSmallIntegerField()
def __str__(self):
return self.name
Then, using formfield_overrides or form below.
formfield_overrides
:
# "admin.py"
from django.contrib import admin
from .models import Product
from django.db import models
from django import forms
@admin.register(Product)
class ProductAdmin(admin.ModelAdmin):
formfield_overrides = { # Here
models.CharField: {
'widget': forms.TextInput(attrs={'size':'50'})
},
models.TextField: {
'widget': forms.Textarea(attrs={'rows':'1', 'cols':'50'})
},
models.DecimalField: {
'widget': forms.NumberInput(attrs={'style': 'width:50ch'})
},
models.PositiveSmallIntegerField: {
'widget': forms.NumberInput(attrs={'style': 'width:50ch'})
},
}
form
:
# "admin.py"
from django.contrib import admin
from .models import Product
from django.db import models
from django import forms
class ProductForm(forms.ModelForm):
class Meta:
widgets = {
'name': forms.TextInput(attrs={'size':'50'}),
'description': forms.Textarea(attrs={'rows':'1', 'cols':'50'}),
'price' : forms.NumberInput(attrs={
'style': 'width:50ch'
}),
'quantity' : forms.NumberInput(attrs={
'style': 'width:50ch'
})
}
@admin.register(Product)
class ProductAdmin(admin.ModelAdmin):
form = ProductForm # Here
form
:
# "admin.py"
from django import forms
from django.contrib import admin
from .models import Product
class ProductForm(forms.ModelForm):
name = forms.CharField(
widget=forms.TextInput(attrs={'size':'50'})
)
description = forms.CharField(
widget=forms.Textarea(attrs={'rows':'1', 'cols':'50'})
)
price = forms.DecimalField(
widget=forms.NumberInput(attrs={'style':'width:50ch'})
)
quantity = forms.IntegerField(
widget=forms.NumberInput(attrs={'style':'width:50ch'})
)
@admin.register(Product)
class ProductAdmin(admin.ModelAdmin):
form = ProductForm # Here
You can change the size of the fields in "Add" and "Change" pages as shown below:
In addition, in this case of only formfield_overrides
, you can change the size of the fields in "Change List" page as shown below:
# "admin.py"
from django.contrib import admin
from .models import Product
from django.db import models
from django import forms
@admin.register(Product)
class ProductAdmin(admin.ModelAdmin):
list_display = ('name', 'description', 'price', 'quantity')
list_editable = ('name',) # Here
list_display_links = ('description',)
formfield_overrides = { # Here
models.CharField: {
'widget': forms.TextInput(attrs={'size':'50'})
},
models.TextField: {
'widget': forms.Textarea(attrs={'rows':'1', 'cols':'50'})
},
models.DecimalField: {
'widget': forms.NumberInput(attrs={'style': 'width:50ch'})
},
models.PositiveSmallIntegerField: {
'widget': forms.NumberInput(attrs={'style': 'width:50ch'})
},
}
- [Django]-How to change the name of a Django app?
- [Django]-Referencing multiple submit buttons in django
- [Django]-In django, how do I sort a model on a field and then get the last item?
-1π
And one more example too :
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
If you want to edit only a specific fields size, you can use this.
- [Django]-Django: accessing session variables from within a template?
- [Django]-<Django object > is not JSON serializable
- [Django]-Reducing Django Memory Usage. Low hanging fruit?