diff --git a/django/contrib/admin/validation.py b/django/contrib/admin/validation.py
index 94d4bbd..f743f2c 100644
a
|
b
|
def validate_base(cls, model):
|
245 | 245 | if type(fields) != tuple: |
246 | 246 | fields = (fields,) |
247 | 247 | for field in fields: |
| 248 | if field in cls.readonly_fields: |
| 249 | # Stuff can be put in fields that isn't actually a |
| 250 | # model field if it's in readonly_fields, |
| 251 | # readonly_fields will handle the validation of such |
| 252 | # things. |
| 253 | continue |
248 | 254 | check_formfield(cls, model, opts, "fieldsets[%d][1]['fields']" % idx, field) |
249 | 255 | try: |
250 | 256 | f = opts.get_field(field) |
diff --git a/tests/regressiontests/admin_validation/models.py b/tests/regressiontests/admin_validation/models.py
index ef65c45..b507648 100644
a
|
b
|
class Album(models.Model):
|
12 | 12 | class Song(models.Model): |
13 | 13 | title = models.CharField(max_length=150) |
14 | 14 | album = models.ForeignKey(Album) |
| 15 | original_release = models.DateField(editable=False) |
15 | 16 | |
16 | 17 | class Meta: |
17 | 18 | ordering = ('title',) |
diff --git a/tests/regressiontests/admin_validation/tests.py b/tests/regressiontests/admin_validation/tests.py
new file mode 100644
index 0000000..9166360
-
|
+
|
|
| 1 | from django.contrib import admin |
| 2 | from django.contrib.admin.validation import validate |
| 3 | from django.test import TestCase |
| 4 | |
| 5 | from models import Song |
| 6 | |
| 7 | |
| 8 | class ValidationTestCase(TestCase): |
| 9 | def test_readonly_and_editable(self): |
| 10 | class SongAdmin(admin.ModelAdmin): |
| 11 | readonly_fields = ["original_release"] |
| 12 | fieldsets = [ |
| 13 | (None, { |
| 14 | "fields": ["title", "original_release"], |
| 15 | }), |
| 16 | ] |
| 17 | |
| 18 | validate(SongAdmin, Song) |