Ticket #4667: newforms-admin-5519-generic-edit-inline-sprint14sep.patch
File newforms-admin-5519-generic-edit-inline-sprint14sep.patch, 8.6 KB (added by , 17 years ago) |
---|
-
django/contrib/admin/options.py
diff --git a/django/contrib/admin/options.py b/django/contrib/admin/options.py index 433be1e..4c7a6bd 100644
a b class InlineModelAdmin(BaseModelAdmin): 689 689 template = None 690 690 verbose_name = None 691 691 verbose_name_plural = None 692 formset = None 692 693 693 694 def __init__(self, parent_model, admin_site): 694 695 self.admin_site = admin_site … … class InlineModelAdmin(BaseModelAdmin): 706 707 fields = flatten_fieldsets(self.declared_fieldsets) 707 708 else: 708 709 fields = None 709 return forms.inline_formset(self.parent_model, self.model, fk_name=self.fk_name, fields=fields, formfield_callback=self.formfield_for_dbfield, extra=self.extra) 710 return forms.inline_formset(self.parent_model, self.model, fk_name=self.fk_name, fields=fields, 711 formfield_callback=self.formfield_for_dbfield, extra=self.extra, formset=self.formset) 710 712 711 713 def formset_change(self, request, obj): 712 714 """Returns an InlineFormSet class for use in admin change views.""" … … class InlineModelAdmin(BaseModelAdmin): 714 716 fields = flatten_fieldsets(self.declared_fieldsets) 715 717 else: 716 718 fields = None 717 return forms.inline_formset(self.parent_model, self.model, fk_name=self.fk_name, fields=fields, formfield_callback=self.formfield_for_dbfield, extra=self.extra) 719 return forms.inline_formset(self.parent_model, self.model, fk_name=self.fk_name, fields=fields, 720 formfield_callback=self.formfield_for_dbfield, extra=self.extra, formset=self.formset) 718 721 719 722 def fieldsets_add(self, request): 720 723 if self.declared_fieldsets: -
django/contrib/contenttypes/generic.py
diff --git a/django/contrib/contenttypes/generic.py b/django/contrib/contenttypes/generic.py index b738a26..ddf3bd1 100644
a b class GenericRel(ManyToManyRel): 260 260 self.multiple = True 261 261 assert not (self.raw_id_admin and self.filter_interface), \ 262 262 "Generic relations may not use both raw_id_admin and filter_interface" 263 264 265 266 from django.newforms.models import InlineFormset, save_instance 267 class GenericInlineFormset(InlineFormset): 268 269 @classmethod 270 def add_fk(cls, parent_model, model, fk_name): 271 from django.template.defaultfilters import slugify 272 assert ':' in fk_name, "Supply valid content_type:object_id as fk_name." 273 274 opts = model._meta 275 ct_field_name, id_field_name = fk_name.split(':') 276 ct = opts.get_field( ct_field_name ) 277 obj_id = opts.get_field( id_field_name ) 278 # HACK: remove the ForeignKey to the parent from every form 279 # This should be done a line above before we pass 'fields' to formset_for_model 280 # an 'omit' argument would be very handy here 281 try: 282 del cls.form_class.base_fields[ct.name] 283 del cls.form_class.base_fields[obj_id.name] 284 except KeyError: 285 pass 286 287 cls.parent_model = parent_model 288 cls.model = model 289 cls.ct_field_name = ct_field_name 290 cls.id_field_name = id_field_name 291 cls.ct = ct 292 cls.obj_id = obj_id 293 cls.rel_name = slugify(fk_name) 294 295 def get_inline_objects(self): 296 # This import is done here to avoid circular import importing this module 297 from django.contrib.contenttypes.models import ContentType 298 if self.instance is None: 299 return [] 300 return self.model._default_manager.filter( **{ 301 self.ct_field_name : ContentType.objects.get_for_model(self.instance), 302 self.id_field_name : self.instance._get_pk_val() 303 }) 304 305 def save_new(self, form, commit=True): 306 # This import is done here to avoid circular import importing this module 307 from django.contrib.contenttypes.models import ContentType 308 kwargs = { 309 self.ct.get_attname(): ContentType.objects.get_for_model(self.instance).id, 310 self.obj_id.get_attname(): self.instance._get_pk_val(), 311 } 312 new_obj = self.model(**kwargs) 313 return save_instance(form, new_obj, commit=commit) -
django/newforms/models.py
diff --git a/django/newforms/models.py b/django/newforms/models.py index bfbc2c2..034f3aa 100644
a b def formset_for_model(model, form=BaseForm, formfield_callback=lambda f: f.formf 289 289 class InlineFormset(BaseModelFormSet): 290 290 """A formset for child objects related to a parent.""" 291 291 def __init__(self, instance=None, data=None, files=None): 292 from django.db.models.fields.related import RelatedObject293 292 self.instance = instance 294 293 # is there a better way to get the object descriptor? 295 self.rel_name = RelatedObject(self.fk.rel.to, self.model, self.fk).get_accessor_name()296 294 super(InlineFormset, self).__init__(data, files, instances=self.get_inline_objects(), prefix=self.rel_name) 295 296 @classmethod 297 def add_fk(cls, parent_model, model, fk_name): 298 from django.db.models import ForeignKey 299 from django.db.models.fields.related import RelatedObject 300 opts = model._meta 301 # figure out what the ForeignKey from model to parent_model is 302 if fk_name is None: 303 fks_to_parent = [f for f in opts.fields if isinstance(f, ForeignKey) and f.rel.to == parent_model] 304 if len(fks_to_parent) == 1: 305 fk = fks_to_parent[0] 306 elif len(fks_to_parent) == 0: 307 raise Exception("%s has no ForeignKey to %s" % (model, parent_model)) 308 else: 309 raise Exception("%s has more than 1 ForeignKey to %s" % (model, parent_model)) 310 else: 311 fk = opts.get_field( fk_name ) 312 # HACK: remove the ForeignKey to the parent from every form 313 # This should be done a line above before we pass 'fields' to formset_for_model 314 # an 'omit' argument would be very handy here 315 try: 316 del cls.form_class.base_fields[fk.name] 317 except KeyError: 318 pass 319 320 cls.parent_model = parent_model 321 cls.fk_name = fk.name 322 cls.rel_name = RelatedObject(fk.rel.to, model, fk).get_accessor_name() 323 cls.fk = fk 297 324 298 325 def get_inline_objects(self): 299 326 if self.instance is None: … … class InlineFormset(BaseModelFormSet): 305 332 new_obj = self.model(**kwargs) 306 333 return save_instance(form, new_obj, commit=commit) 307 334 308 def inline_formset(parent_model, model, fk_name=None, fields=None, extra=3, orderable=False, deletable=True, formfield_callback=lambda f: f.formfield()): 335 def inline_formset(parent_model, model, fk_name=None, fields=None, extra=3, orderable=False, 336 deletable=True, formfield_callback=lambda f: f.formfield(), formset=None): 309 337 """ 310 338 Returns an ``InlineFormset`` for the given kwargs. 311 339 312 340 You must provide ``fk_name`` if ``model`` has more than one ``ForeignKey`` 313 341 to ``parent_model``. 314 342 """ 315 from django.db.models import ForeignKey316 opts = model._meta317 # figure out what the ForeignKey from model to parent_model is318 if fk_name is None:319 fks_to_parent = [f for f in opts.fields if isinstance(f, ForeignKey) and f.rel.to == parent_model]320 if len(fks_to_parent) == 1:321 fk = fks_to_parent[0]322 elif len(fks_to_parent) == 0:323 raise Exception("%s has no ForeignKey to %s" % (model, parent_model))324 else:325 raise Exception("%s has more than 1 ForeignKey to %s" % (model, parent_model))326 343 # let the formset handle object deletion by default 327 FormSet = formset_for_model(model, formset= InlineFormset, fields=fields,328 formfield_callback=formfield_callback, 329 extra=extra, orderable=orderable, 344 FormSet = formset_for_model(model, formset=formset or InlineFormset, fields=fields, 345 formfield_callback=formfield_callback, 346 extra=extra, orderable=orderable, 330 347 deletable=deletable) 331 # HACK: remove the ForeignKey to the parent from every form 332 # This should be done a line above before we pass 'fields' to formset_for_model 333 # an 'omit' argument would be very handy here 334 try: 335 del FormSet.form_class.base_fields[fk.name] 336 except KeyError: 337 pass 338 FormSet.parent_model = parent_model 339 FormSet.fk_name = fk.name 340 FormSet.fk = fk 348 FormSet.add_fk(parent_model, model, fk_name) 341 349 return FormSet