Ticket #4667: newforms-admin-5519-generic-edit-inline.patch
File newforms-admin-5519-generic-edit-inline.patch, 7.8 KB (added by , 17 years ago) |
---|
-
django/contrib/admin/options.py
611 612 def get_inline_formsets(self): 612 613 inline_formset_classes = [] 613 614 for opts in self.inlines: 614 inline = inline_formset(self.model, opts.model, formfield_callback=opts.formfield_for_dbfield, fields=opts.fields, extra=opts.extra) 615 inline = inline_formset( 616 self.model, 617 opts.model, 618 formfield_callback=opts.formfield_for_dbfield, 619 fields=opts.fields, 620 extra=opts.extra, 621 fk_name=opts.name, 622 formset=opts.formset 623 ) 615 624 inline_formset_classes.append(inline) 616 625 return inline_formset_classes 617 626 -
django/contrib/contenttypes/generic.py
- def __init__(self, model, name=None, extra=3, fields=None, template=None, raw_id_fields=None): + def __init__(self, model, name=None, extra=3, fields=None, template=None, raw_id_fields=None, formset=None): self.model = model self.opts = model._meta self.name = name @@ -634,6 +645,7 @@ self.verbose_name_plural = model._meta.verbose_name_plural self.prepopulated_fields = {} self.raw_id_fields = raw_id_fields or () + self.formset = formset class StackedInline(InlineModelAdmin): default_template = 'admin/edit_inline_stacked.html'
258 258 self.multiple = True 259 259 assert not (self.raw_id_admin and self.filter_interface), \ 260 260 "Generic relations may not use both raw_id_admin and filter_interface" 261 262 from django.newforms.models import InlineFormset, save_instance 263 class GenericInlineFormset(InlineFormset): 264 265 @classmethod 266 def add_fk( cls, parent_model, model, fk_name ): 267 assert ':' in fk_name, "Supply valid content_type:object_id as fk_name." 268 269 opts = model._meta 270 ct_field_name, id_field_name = fk_name.split( ':' ) 271 ct = opts.get_field( ct_field_name ) 272 obj_id = opts.get_field( id_field_name ) 273 # HACK: remove the ForeignKey to the parent from every form 274 # This should be done a line above before we pass 'fields' to formset_for_model 275 # an 'omit' argument would be very handy here 276 try: 277 del cls.form_class.base_fields[ct.name] 278 del cls.form_class.base_fields[obj_id.name] 279 except KeyError: 280 pass 281 282 cls.parent_model = parent_model 283 cls.model = model 284 cls.ct_field_name = ct_field_name 285 cls.id_field_name = id_field_name 286 cls.ct = ct 287 cls.obj_id = obj_id 288 289 def get_inline_objects( self ): 290 # This import is done here to avoid circular import importing this module 291 from django.contrib.contenttypes.models import ContentType 292 if self.instance is None: 293 return [] 294 return self.model._default_manager.filter( **{ 295 self.ct_field_name : ContentType.objects.get_for_model( self.instance ), 296 self.id_field_name : self.instance._get_pk_val() 297 }) 298 299 def save_new(self, form, commit=True): 300 # This import is done here to avoid circular import importing this module 301 from django.contrib.contenttypes.models import ContentType 302 kwargs = { 303 self.ct.get_attname(): ContentType.objects.get_for_model( self.instance ).id, 304 self.obj_id.get_attname(): self.instance._get_pk_val(), 305 } 306 new_obj = self.model(**kwargs) 307 return save_instance(form, new_obj, commit=commit) 308 -
django/newforms/models.py
282 282 from django.db.models.fields.related import RelatedObject 283 283 self.instance = instance 284 284 # is there a better way to get the object descriptor? 285 self.rel_name = RelatedObject(self.fk.rel.to, self.model, self.fk).get_accessor_name()286 super(InlineFormset, self).__init__(data, instances=self.get_inline_objects(), prefix= self.rel_name)285 #self.rel_name = RelatedObject(self.fk.rel.to, self.model, self.fk).get_accessor_name() 286 super(InlineFormset, self).__init__(data, instances=self.get_inline_objects(), prefix='aaaa' ) #prefix=self.rel_name) 287 287 288 @classmethod 289 def add_fk( cls, parent_model, model, fk_name ): 290 opts = model._meta 291 # figure out what the ForeignKey from model to parent_model is 292 if fk_name is None: 293 fks_to_parent = [f for f in opts.fields if isinstance(f, ForeignKey) and f.rel.to == parent_model] 294 if len(fks_to_parent) == 1: 295 fk = fks_to_parent[0] 296 elif len(fks_to_parent) == 0: 297 raise Exception("%s has no ForeignKey to %s" % (model, parent_model)) 298 else: 299 raise Exception("%s has more than 1 ForeignKey to %s" % (model, parent_model)) 300 else: 301 fk = opts.get_field( fk_name ) 302 # HACK: remove the ForeignKey to the parent from every form 303 # This should be done a line above before we pass 'fields' to formset_for_model 304 # an 'omit' argument would be very handy here 305 try: 306 del FormSet.form_class.base_fields[fk.name] 307 except KeyError: 308 pass 309 310 cls.parent_model = parent_model 311 cls.fk_name = fk.name 312 cls.fk = fk 313 288 314 def get_inline_objects(self): 289 315 if self.instance is None: 290 316 return [] … … 295 321 new_obj = self.model(**kwargs) 296 322 return save_instance(form, new_obj, commit=commit) 297 323 298 def inline_formset(parent_model, model, fk_name=None, fields=None, extra=3, formfield_callback=lambda f: f.formfield() ):324 def inline_formset(parent_model, model, fk_name=None, fields=None, extra=3, formfield_callback=lambda f: f.formfield(), formset=None): 299 325 """ 300 326 Returns an ``InlineFormset`` for the given kwargs. 301 327 … … 303 329 to ``parent_model``. 304 330 """ 305 331 from django.db.models import ForeignKey 306 opts = model._meta307 # figure out what the ForeignKey from model to parent_model is308 if fk_name is None:309 fks_to_parent = [f for f in opts.fields if isinstance(f, ForeignKey) and f.rel.to == parent_model]310 if len(fks_to_parent) == 1:311 fk = fks_to_parent[0]312 elif len(fks_to_parent) == 0:313 raise Exception("%s has no ForeignKey to %s" % (model, parent_model))314 else:315 raise Exception("%s has more than 1 ForeignKey to %s" % (model, parent_model))316 332 # let the formset handle object deletion by default 317 FormSet = formset_for_model(model, formset=InlineFormset, fields=fields, formfield_callback=formfield_callback, extra=extra, deletable=True) 318 # HACK: remove the ForeignKey to the parent from every form 319 # This should be done a line above before we pass 'fields' to formset_for_model 320 # an 'omit' argument would be very handy here 321 try: 322 del FormSet.form_class.base_fields[fk.name] 323 except KeyError: 324 pass 325 FormSet.parent_model = parent_model 326 FormSet.fk_name = fk.name 327 FormSet.fk = fk 333 FormSet = formset_for_model(model, formset=formset or InlineFormset, fields=fields, formfield_callback=formfield_callback, extra=extra, deletable=True) 334 FormSet.add_fk( parent_model, model, fk_name) 328 335 return FormSet