mirror of https://github.com/django/django.git
Updated BaseGenericInlineFormSet to match the changes made to BaseInlineFormSet in r11874.
git-svn-id: http://code.djangoproject.com/svn/django/trunk@11885 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
c0c6e7d103
commit
fd4cc65baf
|
@ -292,15 +292,27 @@ class BaseGenericInlineFormSet(BaseModelFormSet):
|
||||||
ct_field_name = "content_type"
|
ct_field_name = "content_type"
|
||||||
ct_fk_field_name = "object_id"
|
ct_fk_field_name = "object_id"
|
||||||
|
|
||||||
def __init__(self, data=None, files=None, instance=None, save_as_new=None, prefix=None):
|
def __init__(self, data=None, files=None, instance=None, save_as_new=None,
|
||||||
|
prefix=None, queryset=None):
|
||||||
|
# Avoid a circular import.
|
||||||
|
from django.contrib.contenttypes.models import ContentType
|
||||||
opts = self.model._meta
|
opts = self.model._meta
|
||||||
self.instance = instance
|
self.instance = instance
|
||||||
self.rel_name = '-'.join((
|
self.rel_name = '-'.join((
|
||||||
opts.app_label, opts.object_name.lower(),
|
opts.app_label, opts.object_name.lower(),
|
||||||
self.ct_field.name, self.ct_fk_field.name,
|
self.ct_field.name, self.ct_fk_field.name,
|
||||||
))
|
))
|
||||||
|
if self.instance is None or self.instance.pk is None:
|
||||||
|
qs = self.model._default_manager.none()
|
||||||
|
else:
|
||||||
|
if queryset is None:
|
||||||
|
queryset = self.model._default_manager
|
||||||
|
qs = queryset.filter(**{
|
||||||
|
self.ct_field.name: ContentType.objects.get_for_model(self.instance),
|
||||||
|
self.ct_fk_field.name: self.instance.pk,
|
||||||
|
})
|
||||||
super(BaseGenericInlineFormSet, self).__init__(
|
super(BaseGenericInlineFormSet, self).__init__(
|
||||||
queryset=self.get_queryset(), data=data, files=files,
|
queryset=qs, data=data, files=files,
|
||||||
prefix=prefix
|
prefix=prefix
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -312,19 +324,6 @@ class BaseGenericInlineFormSet(BaseModelFormSet):
|
||||||
))
|
))
|
||||||
get_default_prefix = classmethod(get_default_prefix)
|
get_default_prefix = classmethod(get_default_prefix)
|
||||||
|
|
||||||
def get_queryset(self):
|
|
||||||
# Avoid a circular import.
|
|
||||||
from django.contrib.contenttypes.models import ContentType
|
|
||||||
if self.instance is None or self.instance.pk is None:
|
|
||||||
return self.model._default_manager.none()
|
|
||||||
qs = self.model._default_manager.filter(**{
|
|
||||||
self.ct_field.name: ContentType.objects.get_for_model(self.instance),
|
|
||||||
self.ct_fk_field.name: self.instance.pk,
|
|
||||||
})
|
|
||||||
if not qs.ordered:
|
|
||||||
qs = qs.order_by(self.model._meta.pk.name)
|
|
||||||
return qs
|
|
||||||
|
|
||||||
def save_new(self, form, commit=True):
|
def save_new(self, form, commit=True):
|
||||||
# Avoid a circular import.
|
# Avoid a circular import.
|
||||||
from django.contrib.contenttypes.models import ContentType
|
from django.contrib.contenttypes.models import ContentType
|
||||||
|
|
|
@ -20,7 +20,7 @@ class Media(models.Model):
|
||||||
|
|
||||||
class MediaInline(generic.GenericTabularInline):
|
class MediaInline(generic.GenericTabularInline):
|
||||||
model = Media
|
model = Media
|
||||||
|
|
||||||
class EpisodeAdmin(admin.ModelAdmin):
|
class EpisodeAdmin(admin.ModelAdmin):
|
||||||
inlines = [
|
inlines = [
|
||||||
MediaInline,
|
MediaInline,
|
||||||
|
@ -56,7 +56,7 @@ class MediaMaxNumInline(generic.GenericTabularInline):
|
||||||
model = Media
|
model = Media
|
||||||
extra = 5
|
extra = 5
|
||||||
max_num = 2
|
max_num = 2
|
||||||
|
|
||||||
admin.site.register(EpisodeMaxNum, inlines=[MediaMaxNumInline])
|
admin.site.register(EpisodeMaxNum, inlines=[MediaMaxNumInline])
|
||||||
|
|
||||||
#
|
#
|
||||||
|
|
|
@ -17,7 +17,7 @@ class GenericAdminViewTest(TestCase):
|
||||||
self.original_template_debug = settings.TEMPLATE_DEBUG
|
self.original_template_debug = settings.TEMPLATE_DEBUG
|
||||||
settings.TEMPLATE_DEBUG = True
|
settings.TEMPLATE_DEBUG = True
|
||||||
self.client.login(username='super', password='secret')
|
self.client.login(username='super', password='secret')
|
||||||
|
|
||||||
# Can't load content via a fixture (since the GenericForeignKey
|
# Can't load content via a fixture (since the GenericForeignKey
|
||||||
# relies on content type IDs, which will vary depending on what
|
# relies on content type IDs, which will vary depending on what
|
||||||
# other tests have been run), thus we do it here.
|
# other tests have been run), thus we do it here.
|
||||||
|
@ -25,26 +25,30 @@ class GenericAdminViewTest(TestCase):
|
||||||
self.episode_pk = e.pk
|
self.episode_pk = e.pk
|
||||||
m = Media(content_object=e, url='http://example.com/podcast.mp3')
|
m = Media(content_object=e, url='http://example.com/podcast.mp3')
|
||||||
m.save()
|
m.save()
|
||||||
self.media_pk = m.pk
|
self.mp3_media_pk = m.pk
|
||||||
|
|
||||||
|
m = Media(content_object=e, url='http://example.com/logo.png')
|
||||||
|
m.save()
|
||||||
|
self.png_media_pk = m.pk
|
||||||
|
|
||||||
def tearDown(self):
|
def tearDown(self):
|
||||||
self.client.logout()
|
self.client.logout()
|
||||||
settings.TEMPLATE_DEBUG = self.original_template_debug
|
settings.TEMPLATE_DEBUG = self.original_template_debug
|
||||||
|
|
||||||
def testBasicAddGet(self):
|
def testBasicAddGet(self):
|
||||||
"""
|
"""
|
||||||
A smoke test to ensure GET on the add_view works.
|
A smoke test to ensure GET on the add_view works.
|
||||||
"""
|
"""
|
||||||
response = self.client.get('/generic_inline_admin/admin/generic_inline_admin/episode/add/')
|
response = self.client.get('/generic_inline_admin/admin/generic_inline_admin/episode/add/')
|
||||||
self.failUnlessEqual(response.status_code, 200)
|
self.failUnlessEqual(response.status_code, 200)
|
||||||
|
|
||||||
def testBasicEditGet(self):
|
def testBasicEditGet(self):
|
||||||
"""
|
"""
|
||||||
A smoke test to ensure GET on the change_view works.
|
A smoke test to ensure GET on the change_view works.
|
||||||
"""
|
"""
|
||||||
response = self.client.get('/generic_inline_admin/admin/generic_inline_admin/episode/%d/' % self.episode_pk)
|
response = self.client.get('/generic_inline_admin/admin/generic_inline_admin/episode/%d/' % self.episode_pk)
|
||||||
self.failUnlessEqual(response.status_code, 200)
|
self.failUnlessEqual(response.status_code, 200)
|
||||||
|
|
||||||
def testBasicAddPost(self):
|
def testBasicAddPost(self):
|
||||||
"""
|
"""
|
||||||
A smoke test to ensure POST on add_view works.
|
A smoke test to ensure POST on add_view works.
|
||||||
|
@ -57,7 +61,7 @@ class GenericAdminViewTest(TestCase):
|
||||||
}
|
}
|
||||||
response = self.client.post('/generic_inline_admin/admin/generic_inline_admin/episode/add/', post_data)
|
response = self.client.post('/generic_inline_admin/admin/generic_inline_admin/episode/add/', post_data)
|
||||||
self.failUnlessEqual(response.status_code, 302) # redirect somewhere
|
self.failUnlessEqual(response.status_code, 302) # redirect somewhere
|
||||||
|
|
||||||
def testBasicEditPost(self):
|
def testBasicEditPost(self):
|
||||||
"""
|
"""
|
||||||
A smoke test to ensure POST on edit_view works.
|
A smoke test to ensure POST on edit_view works.
|
||||||
|
@ -65,17 +69,45 @@ class GenericAdminViewTest(TestCase):
|
||||||
post_data = {
|
post_data = {
|
||||||
"name": u"This Week in Django",
|
"name": u"This Week in Django",
|
||||||
# inline data
|
# inline data
|
||||||
"generic_inline_admin-media-content_type-object_id-TOTAL_FORMS": u"2",
|
"generic_inline_admin-media-content_type-object_id-TOTAL_FORMS": u"3",
|
||||||
"generic_inline_admin-media-content_type-object_id-INITIAL_FORMS": u"1",
|
"generic_inline_admin-media-content_type-object_id-INITIAL_FORMS": u"2",
|
||||||
"generic_inline_admin-media-content_type-object_id-0-id": u"%d" % self.media_pk,
|
"generic_inline_admin-media-content_type-object_id-0-id": u"%d" % self.mp3_media_pk,
|
||||||
"generic_inline_admin-media-content_type-object_id-0-url": u"http://example.com/podcast.mp3",
|
"generic_inline_admin-media-content_type-object_id-0-url": u"http://example.com/podcast.mp3",
|
||||||
"generic_inline_admin-media-content_type-object_id-1-id": u"",
|
"generic_inline_admin-media-content_type-object_id-1-id": u"%d" % self.png_media_pk,
|
||||||
"generic_inline_admin-media-content_type-object_id-1-url": u"",
|
"generic_inline_admin-media-content_type-object_id-1-url": u"http://example.com/logo.png",
|
||||||
|
"generic_inline_admin-media-content_type-object_id-2-id": u"",
|
||||||
|
"generic_inline_admin-media-content_type-object_id-2-url": u"",
|
||||||
}
|
}
|
||||||
url = '/generic_inline_admin/admin/generic_inline_admin/episode/%d/' % self.episode_pk
|
url = '/generic_inline_admin/admin/generic_inline_admin/episode/%d/' % self.episode_pk
|
||||||
response = self.client.post(url, post_data)
|
response = self.client.post(url, post_data)
|
||||||
self.failUnlessEqual(response.status_code, 302) # redirect somewhere
|
self.failUnlessEqual(response.status_code, 302) # redirect somewhere
|
||||||
|
|
||||||
|
def testGenericInlineFormset(self):
|
||||||
|
EpisodeMediaFormSet = generic_inlineformset_factory(Media, can_delete=False, extra=3)
|
||||||
|
e = Episode.objects.get(name='This Week in Django')
|
||||||
|
|
||||||
|
# Works with no queryset
|
||||||
|
formset = EpisodeMediaFormSet(instance=e)
|
||||||
|
self.assertEquals(len(formset.forms), 5)
|
||||||
|
self.assertEquals(formset.forms[0].as_p(), '<p><label for="id_generic_inline_admin-media-content_type-object_id-0-url">Url:</label> <input id="id_generic_inline_admin-media-content_type-object_id-0-url" type="text" name="generic_inline_admin-media-content_type-object_id-0-url" value="http://example.com/podcast.mp3" maxlength="200" /><input type="hidden" name="generic_inline_admin-media-content_type-object_id-0-id" value="1" id="id_generic_inline_admin-media-content_type-object_id-0-id" /></p>')
|
||||||
|
self.assertEquals(formset.forms[1].as_p(), '<p><label for="id_generic_inline_admin-media-content_type-object_id-1-url">Url:</label> <input id="id_generic_inline_admin-media-content_type-object_id-1-url" type="text" name="generic_inline_admin-media-content_type-object_id-1-url" value="http://example.com/logo.png" maxlength="200" /><input type="hidden" name="generic_inline_admin-media-content_type-object_id-1-id" value="2" id="id_generic_inline_admin-media-content_type-object_id-1-id" /></p>')
|
||||||
|
self.assertEquals(formset.forms[2].as_p(), '<p><label for="id_generic_inline_admin-media-content_type-object_id-2-url">Url:</label> <input id="id_generic_inline_admin-media-content_type-object_id-2-url" type="text" name="generic_inline_admin-media-content_type-object_id-2-url" maxlength="200" /><input type="hidden" name="generic_inline_admin-media-content_type-object_id-2-id" id="id_generic_inline_admin-media-content_type-object_id-2-id" /></p>')
|
||||||
|
|
||||||
|
# A queryset can be used to alter display ordering
|
||||||
|
formset = EpisodeMediaFormSet(instance=e, queryset=Media.objects.order_by('url'))
|
||||||
|
self.assertEquals(len(formset.forms), 5)
|
||||||
|
self.assertEquals(formset.forms[0].as_p(), '<p><label for="id_generic_inline_admin-media-content_type-object_id-0-url">Url:</label> <input id="id_generic_inline_admin-media-content_type-object_id-0-url" type="text" name="generic_inline_admin-media-content_type-object_id-0-url" value="http://example.com/logo.png" maxlength="200" /><input type="hidden" name="generic_inline_admin-media-content_type-object_id-0-id" value="2" id="id_generic_inline_admin-media-content_type-object_id-0-id" /></p>')
|
||||||
|
self.assertEquals(formset.forms[1].as_p(), '<p><label for="id_generic_inline_admin-media-content_type-object_id-1-url">Url:</label> <input id="id_generic_inline_admin-media-content_type-object_id-1-url" type="text" name="generic_inline_admin-media-content_type-object_id-1-url" value="http://example.com/podcast.mp3" maxlength="200" /><input type="hidden" name="generic_inline_admin-media-content_type-object_id-1-id" value="1" id="id_generic_inline_admin-media-content_type-object_id-1-id" /></p>')
|
||||||
|
self.assertEquals(formset.forms[2].as_p(), '<p><label for="id_generic_inline_admin-media-content_type-object_id-2-url">Url:</label> <input id="id_generic_inline_admin-media-content_type-object_id-2-url" type="text" name="generic_inline_admin-media-content_type-object_id-2-url" maxlength="200" /><input type="hidden" name="generic_inline_admin-media-content_type-object_id-2-id" id="id_generic_inline_admin-media-content_type-object_id-2-id" /></p>')
|
||||||
|
|
||||||
|
|
||||||
|
# Works with a queryset that omits items
|
||||||
|
formset = EpisodeMediaFormSet(instance=e, queryset=Media.objects.filter(url__endswith=".png"))
|
||||||
|
self.assertEquals(len(formset.forms), 4)
|
||||||
|
self.assertEquals(formset.forms[0].as_p(), '<p><label for="id_generic_inline_admin-media-content_type-object_id-0-url">Url:</label> <input id="id_generic_inline_admin-media-content_type-object_id-0-url" type="text" name="generic_inline_admin-media-content_type-object_id-0-url" value="http://example.com/logo.png" maxlength="200" /><input type="hidden" name="generic_inline_admin-media-content_type-object_id-0-id" value="2" id="id_generic_inline_admin-media-content_type-object_id-0-id" /></p>')
|
||||||
|
self.assertEquals(formset.forms[1].as_p(), '<p><label for="id_generic_inline_admin-media-content_type-object_id-1-url">Url:</label> <input id="id_generic_inline_admin-media-content_type-object_id-1-url" type="text" name="generic_inline_admin-media-content_type-object_id-1-url" maxlength="200" /><input type="hidden" name="generic_inline_admin-media-content_type-object_id-1-id" id="id_generic_inline_admin-media-content_type-object_id-1-id" /></p>')
|
||||||
|
|
||||||
|
|
||||||
def testGenericInlineFormsetFactory(self):
|
def testGenericInlineFormsetFactory(self):
|
||||||
# Regression test for #10522.
|
# Regression test for #10522.
|
||||||
inline_formset = generic_inlineformset_factory(Media,
|
inline_formset = generic_inlineformset_factory(Media,
|
||||||
|
|
Loading…
Reference in New Issue