Fixed #12577. Reverted some changes from [12098] since [12206] made them unneccessary. Also, added a test for using generic inlines with unique_together. Thanks for the report, Raffaele Salmaso.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@12268 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Joseph Kocherhans 2010-01-21 01:40:21 +00:00
parent 63c5e6621a
commit 856a39e841
3 changed files with 51 additions and 16 deletions

View File

@ -297,11 +297,7 @@ class BaseGenericInlineFormSet(BaseModelFormSet):
# Avoid a circular import. # Avoid a circular import.
from django.contrib.contenttypes.models import ContentType from django.contrib.contenttypes.models import ContentType
opts = self.model._meta opts = self.model._meta
if instance is None: self.instance = instance
self.instance = self.model()
else:
self.instance = instance
self.save_as_new = save_as_new
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,
@ -328,19 +324,15 @@ class BaseGenericInlineFormSet(BaseModelFormSet):
)) ))
get_default_prefix = classmethod(get_default_prefix) get_default_prefix = classmethod(get_default_prefix)
def _construct_form(self, i, **kwargs): 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
form = super(BaseGenericInlineFormSet, self)._construct_form(i, **kwargs) kwargs = {
if self.save_as_new: self.ct_field.get_attname(): ContentType.objects.get_for_model(self.instance).pk,
# Remove the key from the form's data, we are only creating new instances. self.ct_fk_field.get_attname(): self.instance.pk,
form.data[form.add_prefix(self.ct_fk_field.name)] = None }
form.data[form.add_prefix(self.ct_field.name)] = None new_obj = self.model(**kwargs)
return save_instance(form, new_obj, commit=commit)
# Set the GenericForeignKey value here so that the form can do its validation.
setattr(form.instance, self.ct_fk_field.attname, self.instance.pk)
setattr(form.instance, self.ct_field.attname, ContentType.objects.get_for_model(self.instance).pk)
return form
def generic_inlineformset_factory(model, form=ModelForm, def generic_inlineformset_factory(model, form=ModelForm,
formset=BaseGenericInlineFormSet, formset=BaseGenericInlineFormSet,

View File

@ -72,3 +72,24 @@ class MediaExcludeInline(generic.GenericTabularInline):
admin.site.register(EpisodeExclude, inlines=[MediaExcludeInline]) admin.site.register(EpisodeExclude, inlines=[MediaExcludeInline])
#
# Generic inline with unique_together
#
class PhoneNumber(models.Model):
content_type = models.ForeignKey(ContentType)
object_id = models.PositiveIntegerField()
content_object = generic.GenericForeignKey('content_type', 'object_id')
phone_number = models.CharField(max_length=30)
class Meta:
unique_together = (('content_type', 'object_id', 'phone_number',),)
class Contact(models.Model):
name = models.CharField(max_length=50)
phone_numbers = generic.GenericRelation(PhoneNumber)
class PhoneNumberInline(generic.GenericTabularInline):
model = PhoneNumber
admin.site.register(Contact, inlines=[PhoneNumberInline])

View File

@ -176,3 +176,25 @@ class GenericInlineAdminParametersTest(TestCase):
response = self.client.get('/generic_inline_admin/admin/generic_inline_admin/episodeexclude/%s/' % e.pk) response = self.client.get('/generic_inline_admin/admin/generic_inline_admin/episodeexclude/%s/' % e.pk)
formset = response.context['inline_admin_formsets'][0].formset formset = response.context['inline_admin_formsets'][0].formset
self.failIf('url' in formset.forms[0], 'The formset has excluded "url" field.') self.failIf('url' in formset.forms[0], 'The formset has excluded "url" field.')
class GenericInlineAdminWithUniqueTogetherTest(TestCase):
fixtures = ['users.xml']
def setUp(self):
self.client.login(username='super', password='secret')
def tearDown(self):
self.client.logout()
def testAdd(self):
post_data = {
"name": u"John Doe",
# inline data
"generic_inline_admin-phonenumber-content_type-object_id-TOTAL_FORMS": u"1",
"generic_inline_admin-phonenumber-content_type-object_id-INITIAL_FORMS": u"0",
"generic_inline_admin-phonenumber-content_type-object_id-0-id": "",
"generic_inline_admin-phonenumber-content_type-object_id-0-phone_number": "555-555-5555",
}
response = self.client.get('/generic_inline_admin/admin/generic_inline_admin/contact/add/')
response = self.client.post('/generic_inline_admin/admin/generic_inline_admin/contact/add/', post_data)
self.failUnlessEqual(response.status_code, 302) # redirect somewhere