1 | diff --git a/django/contrib/admin/sites.py b/django/contrib/admin/sites.py
|
---|
2 | index c1f6970..870ab04 100644
|
---|
3 | --- a/django/contrib/admin/sites.py
|
---|
4 | +++ b/django/contrib/admin/sites.py
|
---|
5 | @@ -61,6 +61,8 @@ class AdminSite(object):
|
---|
6 | they'll be applied as options to the admin class.
|
---|
7 |
|
---|
8 | If a model is already registered, this will raise AlreadyRegistered.
|
---|
9 | +
|
---|
10 | + If a model is abstract, this will raise ImproperlyConfigured.
|
---|
11 | """
|
---|
12 | if not admin_class:
|
---|
13 | admin_class = ModelAdmin
|
---|
14 | @@ -74,6 +76,10 @@ class AdminSite(object):
|
---|
15 | if isinstance(model_or_iterable, ModelBase):
|
---|
16 | model_or_iterable = [model_or_iterable]
|
---|
17 | for model in model_or_iterable:
|
---|
18 | + if model._meta.abstract:
|
---|
19 | + raise ImproperlyConfigured('The model %s is abstract and '
|
---|
20 | + 'therefore cannot be registered' % model.__name__)
|
---|
21 | +
|
---|
22 | if model in self._registry:
|
---|
23 | raise AlreadyRegistered('The model %s is already registered' % model.__name__)
|
---|
24 |
|
---|
25 | diff --git a/tests/regressiontests/admin_views/models.py b/tests/regressiontests/admin_views/models.py
|
---|
26 | index 9ac99cc..bd3b956 100644
|
---|
27 | --- a/tests/regressiontests/admin_views/models.py
|
---|
28 | +++ b/tests/regressiontests/admin_views/models.py
|
---|
29 | @@ -641,8 +641,13 @@ class CyclicTwo(models.Model):
|
---|
30 | class Topping(models.Model):
|
---|
31 | name = models.CharField(max_length=20)
|
---|
32 |
|
---|
33 | -class Pizza(models.Model):
|
---|
34 | +class AbstractPizza(models.Model):
|
---|
35 | name = models.CharField(max_length=20)
|
---|
36 | +
|
---|
37 | + class Meta:
|
---|
38 | + abstract = True
|
---|
39 | +
|
---|
40 | +class Pizza(AbstractPizza):
|
---|
41 | toppings = models.ManyToManyField('Topping')
|
---|
42 |
|
---|
43 | class PizzaAdmin(admin.ModelAdmin):
|
---|
44 | diff --git a/tests/regressiontests/admin_views/tests.py b/tests/regressiontests/admin_views/tests.py
|
---|
45 | index bbef907..a5cf305 100644
|
---|
46 | --- a/tests/regressiontests/admin_views/tests.py
|
---|
47 | +++ b/tests/regressiontests/admin_views/tests.py
|
---|
48 | @@ -6,7 +6,7 @@ import urlparse
|
---|
49 |
|
---|
50 | from django.conf import settings
|
---|
51 | from django.core import mail
|
---|
52 | -from django.core.exceptions import SuspiciousOperation
|
---|
53 | +from django.core.exceptions import SuspiciousOperation, ImproperlyConfigured
|
---|
54 | from django.core.files import temp as tempfile
|
---|
55 | from django.core.urlresolvers import reverse
|
---|
56 | # Register auth models with the admin.
|
---|
57 | @@ -36,7 +36,7 @@ from models import (Article, BarAccount, CustomArticle, EmptyModel,
|
---|
58 | Language, Collector, Widget, Grommet, DooHickey, FancyDoodad, Whatsit,
|
---|
59 | Category, Post, Plot, FunkyTag, Chapter, Book, Promo, WorkHour, Employee,
|
---|
60 | Question, Answer, Inquisition, Actor, FoodDelivery,
|
---|
61 | - RowLevelChangePermissionModel, Paper, CoverLetter)
|
---|
62 | + RowLevelChangePermissionModel, Paper, CoverLetter, AbstractPizza)
|
---|
63 |
|
---|
64 |
|
---|
65 | class AdminViewBasicTest(TestCase):
|
---|
66 | @@ -530,6 +530,19 @@ class CustomModelAdminTest(AdminViewBasicTest):
|
---|
67 | response = self.client.get('/test_admin/%s/my_view/' % self.urlbit)
|
---|
68 | self.assert_(response.content == "Django is a magical pony!", response.content)
|
---|
69 |
|
---|
70 | +class AdminRegistrationTest(TestCase):
|
---|
71 | +
|
---|
72 | + def testAbstractModel(self):
|
---|
73 | + """
|
---|
74 | + Exception is raised when trying to register an abstract model.
|
---|
75 | + Refs #12004.
|
---|
76 | + """
|
---|
77 | + from django.contrib.admin import site
|
---|
78 | + # Smoke test to determine whether admin site works at all
|
---|
79 | + response = self.client.get('/test_admin/admin/admin_views/pizza/')
|
---|
80 | + self.failUnlessEqual(response.status_code, 200)
|
---|
81 | + self.assertRaises(ImproperlyConfigured, site.register, AbstractPizza)
|
---|
82 | +
|
---|
83 | def get_perm(Model, perm):
|
---|
84 | """Return the permission object, for the Model"""
|
---|
85 | ct = ContentType.objects.get_for_model(Model)
|
---|