Fixed #16418 -- Made generic views work with ModelForms
Generic views assumed any object's _meta will be model Options. This is not true for ModelForms for example. Took isinstance(obj, Model) in use instead.
This commit is contained in:
parent
a035d9d650
commit
484fcd34a4
|
@ -1,6 +1,7 @@
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
from django.core.exceptions import ImproperlyConfigured, ObjectDoesNotExist
|
from django.core.exceptions import ImproperlyConfigured, ObjectDoesNotExist
|
||||||
|
from django.db import models
|
||||||
from django.http import Http404
|
from django.http import Http404
|
||||||
from django.utils.translation import ugettext as _
|
from django.utils.translation import ugettext as _
|
||||||
from django.views.generic.base import TemplateResponseMixin, ContextMixin, View
|
from django.views.generic.base import TemplateResponseMixin, ContextMixin, View
|
||||||
|
@ -81,7 +82,7 @@ class SingleObjectMixin(ContextMixin):
|
||||||
"""
|
"""
|
||||||
if self.context_object_name:
|
if self.context_object_name:
|
||||||
return self.context_object_name
|
return self.context_object_name
|
||||||
elif hasattr(obj, '_meta'):
|
elif isinstance(obj, models.Model):
|
||||||
return obj._meta.object_name.lower()
|
return obj._meta.object_name.lower()
|
||||||
else:
|
else:
|
||||||
return None
|
return None
|
||||||
|
@ -128,13 +129,13 @@ class SingleObjectTemplateResponseMixin(TemplateResponseMixin):
|
||||||
|
|
||||||
# The least-specific option is the default <app>/<model>_detail.html;
|
# The least-specific option is the default <app>/<model>_detail.html;
|
||||||
# only use this if the object in question is a model.
|
# only use this if the object in question is a model.
|
||||||
if hasattr(self.object, '_meta'):
|
if isinstance(self.object, models.Model):
|
||||||
names.append("%s/%s%s.html" % (
|
names.append("%s/%s%s.html" % (
|
||||||
self.object._meta.app_label,
|
self.object._meta.app_label,
|
||||||
self.object._meta.object_name.lower(),
|
self.object._meta.object_name.lower(),
|
||||||
self.template_name_suffix
|
self.template_name_suffix
|
||||||
))
|
))
|
||||||
elif hasattr(self, 'model') and hasattr(self.model, '_meta'):
|
elif hasattr(self, 'model') and self.model is not None and issubclass(self.model, models.Model):
|
||||||
names.append("%s/%s%s.html" % (
|
names.append("%s/%s%s.html" % (
|
||||||
self.model._meta.app_label,
|
self.model._meta.app_label,
|
||||||
self.model._meta.object_name.lower(),
|
self.model._meta.object_name.lower(),
|
||||||
|
|
|
@ -92,3 +92,8 @@ class DetailViewTest(TestCase):
|
||||||
|
|
||||||
def test_invalid_queryset(self):
|
def test_invalid_queryset(self):
|
||||||
self.assertRaises(ImproperlyConfigured, self.client.get, '/detail/author/invalid/qs/')
|
self.assertRaises(ImproperlyConfigured, self.client.get, '/detail/author/invalid/qs/')
|
||||||
|
|
||||||
|
def test_non_model_object_with_meta(self):
|
||||||
|
res = self.client.get('/detail/nonmodel/1/')
|
||||||
|
self.assertEqual(res.status_code, 200)
|
||||||
|
self.assertEqual(res.context['object'].id, "non_model_1")
|
||||||
|
|
|
@ -53,6 +53,8 @@ urlpatterns = patterns('',
|
||||||
views.AuthorDetail.as_view()),
|
views.AuthorDetail.as_view()),
|
||||||
(r'^detail/author/invalid/qs/$',
|
(r'^detail/author/invalid/qs/$',
|
||||||
views.AuthorDetail.as_view(queryset=None)),
|
views.AuthorDetail.as_view(queryset=None)),
|
||||||
|
(r'^detail/nonmodel/1/$',
|
||||||
|
views.NonModelDetail.as_view()),
|
||||||
|
|
||||||
# Create/UpdateView
|
# Create/UpdateView
|
||||||
(r'^edit/artists/create/$',
|
(r'^edit/artists/create/$',
|
||||||
|
|
|
@ -226,3 +226,18 @@ class BookSigningTodayArchive(BookSigningConfig, generic.TodayArchiveView):
|
||||||
|
|
||||||
class BookSigningDetail(BookSigningConfig, generic.DateDetailView):
|
class BookSigningDetail(BookSigningConfig, generic.DateDetailView):
|
||||||
context_object_name = 'book'
|
context_object_name = 'book'
|
||||||
|
|
||||||
|
|
||||||
|
class NonModel(object):
|
||||||
|
id = "non_model_1"
|
||||||
|
|
||||||
|
_meta = None
|
||||||
|
|
||||||
|
|
||||||
|
class NonModelDetail(generic.DetailView):
|
||||||
|
|
||||||
|
template_name = 'generic_views/detail.html'
|
||||||
|
model = NonModel
|
||||||
|
|
||||||
|
def get_object(self, queryset=None):
|
||||||
|
return NonModel()
|
||||||
|
|
Loading…
Reference in New Issue