diff options
| author | Brian Rosner <brosner@gmail.com> | 2009-12-22 18:29:00 +0000 |
|---|---|---|
| committer | Brian Rosner <brosner@gmail.com> | 2009-12-22 18:29:00 +0000 |
| commit | bcd9482a2019158f4580c24cd50ee8bfae9b2739 (patch) | |
| tree | af1de2b3e36b78d4fb820fe033acb4041eef09d0 /tests/regressiontests | |
| parent | 9233d0426537615e06b78d28010d17d5a66adf44 (diff) | |
Fixed #342 -- added readonly_fields to ModelAdmin. Thanks Alex Gaynor for bootstrapping the patch.
ModelAdmin has been given a readonly_fields that allow field and calculated
values to be displayed alongside editable fields. This works on model
add/change pages and inlines.
git-svn-id: http://code.djangoproject.com/svn/django/trunk@11965 bcc190cf-cafb-0310-a4f2-bffc1f526a37
Diffstat (limited to 'tests/regressiontests')
| -rw-r--r-- | tests/regressiontests/admin_validation/models.py | 61 | ||||
| -rw-r--r-- | tests/regressiontests/admin_views/models.py | 50 | ||||
| -rw-r--r-- | tests/regressiontests/admin_views/tests.py | 59 |
3 files changed, 162 insertions, 8 deletions
diff --git a/tests/regressiontests/admin_validation/models.py b/tests/regressiontests/admin_validation/models.py index eb53a9dd6e..682fca66de 100644 --- a/tests/regressiontests/admin_validation/models.py +++ b/tests/regressiontests/admin_validation/models.py @@ -19,6 +19,10 @@ class Song(models.Model): def __unicode__(self): return self.title + def readonly_method_on_model(self): + # does nothing + pass + class TwoAlbumFKAndAnE(models.Model): album1 = models.ForeignKey(Album, related_name="album1_set") @@ -110,6 +114,63 @@ Exception: <class 'regressiontests.admin_validation.models.TwoAlbumFKAndAnE'> ha >>> validate_inline(TwoAlbumFKAndAnEInline, None, Album) +>>> class SongAdmin(admin.ModelAdmin): +... readonly_fields = ("title",) + +>>> validate(SongAdmin, Song) + +>>> def my_function(obj): +... # does nothing +... pass +>>> class SongAdmin(admin.ModelAdmin): +... readonly_fields = (my_function,) + +>>> validate(SongAdmin, Song) + +>>> class SongAdmin(admin.ModelAdmin): +... readonly_fields = ("readonly_method_on_modeladmin",) +... +... def readonly_method_on_modeladmin(self, obj): +... # does nothing +... pass + +>>> validate(SongAdmin, Song) + +>>> class SongAdmin(admin.ModelAdmin): +... readonly_fields = ("readonly_method_on_model",) + +>>> validate(SongAdmin, Song) + +>>> class SongAdmin(admin.ModelAdmin): +... readonly_fields = ("title", "nonexistant") + +>>> validate(SongAdmin, Song) +Traceback (most recent call last): + ... +ImproperlyConfigured: SongAdmin.readonly_fields[1], 'nonexistant' is not a callable or an attribute of 'SongAdmin' or found in the model 'Song'. + +>>> class SongAdmin(admin.ModelAdmin): +... readonly_fields = ("title", "awesome_song") +... fields = ("album", "title", "awesome_song") + +>>> validate(SongAdmin, Song) +Traceback (most recent call last): + ... +ImproperlyConfigured: SongAdmin.readonly_fields[1], 'awesome_song' is not a callable or an attribute of 'SongAdmin' or found in the model 'Song'. + +>>> class SongAdmin(SongAdmin): +... def awesome_song(self, instance): +... if instance.title == "Born to Run": +... return "Best Ever!" +... return "Status unknown." + +>>> validate(SongAdmin, Song) + +>>> class SongAdmin(admin.ModelAdmin): +... readonly_fields = (lambda obj: "test",) + +>>> validate(SongAdmin, Song) + # Regression test for #12203/#12237 - Fail more gracefully when a M2M field that # specifies the 'through' option is included in the 'fields' or the 'fieldsets' # ModelAdmin options. diff --git a/tests/regressiontests/admin_views/models.py b/tests/regressiontests/admin_views/models.py index 97785c50f9..ffdc72620e 100644 --- a/tests/regressiontests/admin_views/models.py +++ b/tests/regressiontests/admin_views/models.py @@ -1,11 +1,14 @@ # -*- coding: utf-8 -*- +import datetime import tempfile import os -from django.core.files.storage import FileSystemStorage -from django.db import models + from django.contrib import admin +from django.core.files.storage import FileSystemStorage from django.contrib.admin.views.main import ChangeList from django.core.mail import EmailMessage +from django.db import models + class Section(models.Model): """ @@ -419,7 +422,47 @@ class CategoryInline(admin.StackedInline): model = Category class CollectorAdmin(admin.ModelAdmin): - inlines = [WidgetInline, DooHickeyInline, GrommetInline, WhatsitInline, FancyDoodadInline, CategoryInline] + inlines = [ + WidgetInline, DooHickeyInline, GrommetInline, WhatsitInline, + FancyDoodadInline, CategoryInline + ] + +class Link(models.Model): + posted = models.DateField( + default=lambda: datetime.date.today() - datetime.timedelta(days=7) + ) + url = models.URLField() + post = models.ForeignKey("Post") + + +class LinkInline(admin.TabularInline): + model = Link + extra = 1 + + readonly_fields = ("posted",) + + +class Post(models.Model): + title = models.CharField(max_length=100) + content = models.TextField() + posted = models.DateField(default=datetime.date.today) + + def awesomeness_level(self): + return "Very awesome." + +class PostAdmin(admin.ModelAdmin): + readonly_fields = ('posted', 'awesomeness_level', 'coolness', lambda obj: "foo") + + inlines = [ + LinkInline + ] + + def coolness(self, instance): + if instance.pk: + return "%d amount of cool." % instance.pk + else: + return "Unkown coolness." + class Gadget(models.Model): name = models.CharField(max_length=100) @@ -458,6 +501,7 @@ admin.site.register(Recommendation, RecommendationAdmin) admin.site.register(Recommender) admin.site.register(Collector, CollectorAdmin) admin.site.register(Category, CategoryAdmin) +admin.site.register(Post, PostAdmin) admin.site.register(Gadget, GadgetAdmin) # We intentionally register Promo and ChapterXtra1 but not Chapter nor ChapterXtra2. diff --git a/tests/regressiontests/admin_views/tests.py b/tests/regressiontests/admin_views/tests.py index 8e156899a1..320b632537 100644 --- a/tests/regressiontests/admin_views/tests.py +++ b/tests/regressiontests/admin_views/tests.py @@ -10,20 +10,18 @@ from django.contrib.admin.models import LogEntry, DELETION from django.contrib.admin.sites import LOGIN_FORM_KEY from django.contrib.admin.util import quote from django.contrib.admin.helpers import ACTION_CHECKBOX_NAME +from django.utils import formats from django.utils.cache import get_max_age from django.utils.html import escape +from django.utils.translation import get_date_formats # local test models from models import Article, BarAccount, CustomArticle, EmptyModel, \ ExternalSubscriber, FooAccount, Gallery, ModelWithStringPrimaryKey, \ Person, Persona, Picture, Podcast, Section, Subscriber, Vodcast, \ Language, Collector, Widget, Grommet, DooHickey, FancyDoodad, Whatsit, \ - Category + Category, Post -try: - set -except NameError: - from sets import Set as set class AdminViewBasicTest(TestCase): fixtures = ['admin-views-users.xml', 'admin-views-colors.xml', 'admin-views-fabrics.xml'] @@ -1688,3 +1686,54 @@ class NeverCacheTests(TestCase): "Check the never-cache status of the Javascript i18n view" response = self.client.get('/test_admin/jsi18n/') self.failUnlessEqual(get_max_age(response), None) + + +class ReadonlyTest(TestCase): + fixtures = ['admin-views-users.xml'] + + def setUp(self): + self.client.login(username='super', password='secret') + + def tearDown(self): + self.client.logout() + + def test_readonly_get(self): + response = self.client.get('/test_admin/admin/admin_views/post/add/') + self.assertEqual(response.status_code, 200) + self.assertNotContains(response, 'name="posted"') + # 3 fields + 2 submit buttons + 2 inline management form fields, + 2 + # hidden fields for inlines + 1 field for the inline + self.assertEqual(response.content.count("input"), 10) + self.assertContains(response, formats.localize(datetime.date.today())) + self.assertContains(response, + "<label>Awesomeness level:</label>") + self.assertContains(response, "Very awesome.") + self.assertContains(response, "Unkown coolness.") + self.assertContains(response, "foo") + self.assertContains(response, + formats.localize(datetime.date.today() - datetime.timedelta(days=7)) + ) + + p = Post.objects.create(title="I worked on readonly_fields", content="Its good stuff") + response = self.client.get('/test_admin/admin/admin_views/post/%d/' % p.pk) + self.assertContains(response, "%d amount of cool" % p.pk) + + def test_readonly_post(self): + data = { + "title": "Django Got Readonly Fields", + "content": "This is an incredible development.", + "link_set-TOTAL_FORMS": "1", + "link_set-INITIAL_FORMS": "0", + } + response = self.client.post('/test_admin/admin/admin_views/post/add/', data) + self.assertEqual(response.status_code, 302) + self.assertEqual(Post.objects.count(), 1) + p = Post.objects.get() + self.assertEqual(p.posted, datetime.date.today()) + + data["posted"] = "10-8-1990" # some date that's not today + response = self.client.post('/test_admin/admin/admin_views/post/add/', data) + self.assertEqual(response.status_code, 302) + self.assertEqual(Post.objects.count(), 2) + p = Post.objects.order_by('-id')[0] + self.assertEqual(p.posted, datetime.date.today()) |
