Ticket #3987: customfilters.diff
File customfilters.diff, 7.8 KB (added by , 18 years ago) |
---|
-
db/models/fields/related.py
545 545 setattr(cls, related.get_accessor_name(), ForeignRelatedObjectsDescriptor(related)) 546 546 547 547 def formfield(self, **kwargs): 548 defaults = {'queryset': self.rel.to._default_manager.all(), 'required': not self.blank, 'label': capfirst(self.verbose_name), 'help_text': self.help_text} 548 filter_field = kwargs.get('filter', {}) 549 if kwargs.has_key('filter'): del kwargs['filter'] 550 defaults = {'queryset': self.rel.to._default_manager.all().filter(**filter_field), 'required': not self.blank, 'label': capfirst(self.verbose_name), 'help_text': self.help_text} 549 551 defaults.update(kwargs) 550 552 return forms.ModelChoiceField(**defaults) 551 553 … … 606 608 cls._meta.one_to_one_field = self 607 609 608 610 def formfield(self, **kwargs): 609 defaults = {'queryset': self.rel.to._default_manager.all(), 'required': not self.blank, 'label': capfirst(self.verbose_name), 'help_text': self.help_text} 611 filter_field = kwargs.get('filter', {}) 612 if kwargs.has_key('filter'): del kwargs['filter'] 613 defaults = {'queryset': self.rel.to._default_manager.all().filter(**filter_field), 'required': not self.blank, 'label': capfirst(self.verbose_name), 'help_text': self.help_text} 610 614 defaults.update(kwargs) 611 615 return forms.ModelChoiceField(**defaults) 612 616 … … 714 718 def formfield(self, **kwargs): 715 719 # If initial is passed in, it's a list of related objects, but the 716 720 # MultipleChoiceField takes a list of IDs. 721 filter_field = kwargs.get('filter', {}) 722 if kwargs.has_key('filter'): del kwargs['filter'] 717 723 if kwargs.get('initial') is not None: 718 724 kwargs['initial'] = [i._get_pk_val() for i in kwargs['initial']] 719 defaults = {'queryset' : self.rel.to._default_manager.all() , 'required': not self.blank, 'label': capfirst(self.verbose_name), 'help_text': self.help_text}725 defaults = {'queryset' : self.rel.to._default_manager.all().filter(**filter_field), 'required': not self.blank, 'label': capfirst(self.verbose_name), 'help_text': self.help_text} 720 726 defaults.update(kwargs) 721 727 return forms.ModelMultipleChoiceField(**defaults) 722 728 -
contrib/admin/options.py
208 208 209 209 If kwargs are given, they're passed to the form Field's constructor. 210 210 """ 211 filter_field = kwargs.get('filter_field', {}) 212 if kwargs.has_key('filter_field'): del kwargs['filter_field'] 211 213 # For ManyToManyFields with a filter interface, use a special Widget. 212 214 if isinstance(db_field, models.ManyToManyField) and db_field.name in (self.filter_vertical + self.filter_horizontal): 213 215 kwargs['widget'] = widgets.FilteredSelectMultiple(db_field.verbose_name, (db_field.name in self.filter_vertical)) 214 return db_field.formfield( **kwargs)216 return db_field.formfield(filter=filter_field, **kwargs) 215 217 216 218 # For DateTimeFields, use a special field and widget. 217 219 if isinstance(db_field, models.DateTimeField): … … 233 235 if isinstance(db_field, (models.ForeignKey, models.ManyToManyField)): 234 236 if isinstance(db_field, models.ForeignKey) and db_field.name in self.raw_id_fields: 235 237 kwargs['widget'] = widgets.ForeignKeyRawIdWidget(db_field.rel) 236 return db_field.formfield( **kwargs)238 return db_field.formfield(filter=filter_field, **kwargs) 237 239 else: 238 240 # Wrap the widget's render() method with a method that adds 239 241 # extra HTML to the end of the rendered output. 240 formfield = db_field.formfield( **kwargs)242 formfield = db_field.formfield(filter=filter_field, **kwargs) 241 243 formfield.widget.render = widgets.RelatedFieldWidgetWrapper(formfield.widget.render, db_field.rel) 242 244 return formfield 243 245 … … 375 377 request.user.message_set.create(message=msg) 376 378 return HttpResponseRedirect("../") 377 379 378 def add_view(self, request, form_url='' ):380 def add_view(self, request, form_url='', fields_filters={}): 379 381 "The 'add' admin view for this model." 380 382 from django.contrib.admin.views.main import render_change_form 381 383 model = self.model … … 392 394 # Object list will give 'Permission Denied', so go back to admin home 393 395 post_url = '../../../' 394 396 395 ModelForm = forms.form_for_model(model, formfield_callback=self.formfield_for_dbfield )397 ModelForm = forms.form_for_model(model, formfield_callback=self.formfield_for_dbfield, fields_filters=fields_filters) 396 398 397 399 if request.POST: 398 400 new_data = request.POST.copy() … … 413 415 }) 414 416 return render_change_form(self, model, model.AddManipulator(), c, add=True) 415 417 416 def change_view(self, request, object_id ):418 def change_view(self, request, object_id, fields_filters={}): 417 419 "The 'change' admin view for this model." 418 420 from django.contrib.admin.views.main import render_change_form 419 421 model = self.model … … 437 439 if request.POST and request.POST.has_key("_saveasnew"): 438 440 return self.add_view(request, form_url='../../add/') 439 441 440 ModelForm = forms.form_for_instance(obj, formfield_callback=self.formfield_for_dbfield )442 ModelForm = forms.form_for_instance(obj, formfield_callback=self.formfield_for_dbfield, fields_filters=fields_filters) 441 443 442 444 if request.POST: 443 445 new_data = request.POST.copy() -
newforms/models.py
56 56 return save_instance(self, instance, commit) 57 57 return save 58 58 59 def form_for_model(model, form=BaseForm, formfield_callback=lambda f: f.formfield() ):59 def form_for_model(model, form=BaseForm, formfield_callback=lambda f: f.formfield(), fields_filters={}): 60 60 """ 61 61 Returns a Form class for the given Django model class. 62 62 … … 71 71 for f in opts.fields + opts.many_to_many: 72 72 if not f.editable: 73 73 continue 74 formfield = formfield_callback(f) 74 filter_field = fields_filters.get(f.name) 75 if filter_field: 76 formfield = formfield_callback(f, filter_field=filter_field) 77 else: 78 formfield = formfield_callback(f) 75 79 if formfield: 76 80 field_list.append((f.name, formfield)) 77 81 fields = SortedDictFromList(field_list) 78 82 return type(opts.object_name + 'Form', (form,), {'base_fields': fields, '_model': model, 'save': model_save}) 79 83 80 def form_for_instance(instance, form=BaseForm, f ormfield_callback=lambda f, **kwargs: f.formfield(**kwargs)):84 def form_for_instance(instance, form=BaseForm, fields_filters={}, formfield_callback=lambda f, **kwargs: f.formfield(**kwargs)): 81 85 """ 82 86 Returns a Form class for the given Django model instance. 83 87 … … 95 99 if not f.editable: 96 100 continue 97 101 current_value = f.value_from_object(instance) 98 formfield = formfield_callback(f, initial=current_value) 102 filter_field = fields_filters.get(f.name) 103 if filter_field: 104 formfield = formfield_callback(f, filter_field=filter_field, initial=current_value) 105 else: 106 formfield = formfield_callback(f, initial=current_value) 99 107 if formfield: 100 108 field_list.append((f.name, formfield)) 101 109 fields = SortedDictFromList(field_list)