Ticket #3987: diff-dynamic.diff

File diff-dynamic.diff, 7.7 KB (added by Baptiste <baptiste.goupil@…>, 8 years ago)

new patch (cleaner ?)

  • db/models/fields/related.py

     
    544544        setattr(cls, related.get_accessor_name(), ForeignRelatedObjectsDescriptor(related))
    545545
    546546    def formfield(self, **kwargs):
    547         defaults = {'form_class': forms.ModelChoiceField, 'queryset': self.rel.to._default_manager.all()}
     547        defaults = {'form_class': forms.ModelChoiceField}
     548        #To prevent an useless query
     549        if not 'queryset' in kwargs:
     550            defaults['queryset'] = self.rel.to._default_manager.all()
    548551        defaults.update(kwargs)
    549552        return super(ForeignKey, self).formfield(**defaults)
    550553
     
    605608            cls._meta.one_to_one_field = self
    606609
    607610    def formfield(self, **kwargs):
    608         defaults = {'form_class': forms.ModelChoiceField, 'queryset': self.rel.to._default_manager.all()}
     611        defaults = {'form_class': forms.ModelChoiceField}
     612        if not 'queryset' in kwargs:
     613            defaults['queryset'] = self.rel.to._default_manager.all()
    609614        defaults.update(kwargs)
    610615        return super(OneToOneField, self).formfield(**defaults)
    611616
     
    711716        return getattr(obj, self.attname).all()
    712717
    713718    def formfield(self, **kwargs):
    714         defaults = {'form_class': forms.ModelMultipleChoiceField, 'queryset': self.rel.to._default_manager.all()}
     719        defaults = {'form_class': forms.ModelMultipleChoiceField}
     720        if not 'queryset' in kwargs:
     721            defaults['queryset'] = self.rel.to._default_manager.all()
    715722        defaults.update(kwargs)
    716723        # If initial is passed in, it's a list of related objects, but the
    717724        # MultipleChoiceField takes a list of IDs.
  • contrib/admin/options.py

     
    103103    raw_id_fields = ()
    104104    fields = None
    105105
    106     def formfield_for_dbfield(self, db_field, **kwargs):
     106    def formfield_for_dbfield(self, db_field, request, **kwargs):
    107107        """
    108108        Hook for specifying the form Field instance for a given database Field
    109109        instance.
     
    113113        # For ManyToManyFields with a filter interface, use a special widget.
    114114        if isinstance(db_field, models.ManyToManyField) and db_field.name in (self.filter_vertical + self.filter_horizontal):
    115115            kwargs['widget'] = widgets.FilteredSelectMultiple(db_field.verbose_name, (db_field.name in self.filter_vertical))
    116             return db_field.formfield(**kwargs)
     116            if hasattr(self, 'dynamic_%s_choices' % db_field.name):
     117                formfield = db_field.formfield(queryset = getattr(self, 'dynamic_%s_choices' % db_field.name)(request, db_field.rel.to), **kwargs)
    117118
    118119        # For DateTimeFields, use a special field and widget.
    119120        if isinstance(db_field, models.DateTimeField):
     
    133134
    134135        # For ForeignKey or ManyToManyFields, use a special widget.
    135136        if isinstance(db_field, (models.ForeignKey, models.ManyToManyField)):
     137            if hasattr(self, 'dynamic_%s_choices' % db_field.name):
     138                formfield = db_field.formfield(queryset = getattr(self, 'dynamic_%s_choices' % db_field.name)(request, db_field.rel.to), **kwargs)
     139            else:
     140                formfield = db_field.formfield(**kwargs)
    136141            if isinstance(db_field, models.ForeignKey) and db_field.name in self.raw_id_fields:
    137                 kwargs['widget'] = widgets.ForeignKeyRawIdWidget(db_field.rel)
    138                 return db_field.formfield(**kwargs)
     142                formfield.widget = widgets.ForeignKeyRawIdWidget(db_field.rel)
    139143            else:
    140144                # Wrap the widget's render() method with a method that adds
    141145                # extra HTML to the end of the rendered output.
    142                 formfield = db_field.formfield(**kwargs)
    143146                formfield.widget.render = widgets.RelatedFieldWidgetWrapper(formfield.widget.render, db_field.rel)
    144                 return formfield
     147            return formfield
     148       
     149        if isinstance(db_field, (models.OneToOneField)) and hasattr(self, 'dynamic_%s_choices' % db_field.name):
     150            return db_field.formfield(queryset = getattr(self, 'dynamic_%s_choices' % db_field.name)(request, db_field.rel.to), **kwargs)
    145151
    146152        # For any other type of field, just call its formfield() method.
    147153        return db_field.formfield(**kwargs)
    148154
     155
    149156class ModelAdmin(BaseModelAdmin):
    150157    "Encapsulates all admin options and functionality for a given model."
    151158
     
    413420        else:
    414421            # Object list will give 'Permission Denied', so go back to admin home
    415422            post_url = '../../../'
     423       
     424        ModelForm = forms.form_for_model(model, formfield_callback=lambda f: self.formfield_for_dbfield(f, request))
    416425
    417         ModelForm = forms.form_for_model(model, formfield_callback=self.formfield_for_dbfield)
    418 
    419426        inline_formsets = []
    420427        if request.POST:
    421428            new_data = request.POST.copy()
    422429            if opts.has_field_type(models.FileField):
    423430                new_data.update(request.FILES)
    424431            form = ModelForm(new_data)
    425             for FormSet in self.get_inline_formsets():
     432            for FormSet in self.get_inline_formsets(request):
    426433                inline_formset = FormSet(data=new_data)
    427434                inline_formsets.append(inline_formset)
    428435            if all_valid(inline_formsets) and form.is_valid():
    429436                return self.save_add(request, model, form, inline_formsets, '../%s/')
    430437        else:
    431438            form = ModelForm(initial=request.GET)
    432             for FormSet in self.get_inline_formsets():
     439            for FormSet in self.get_inline_formsets(request):
    433440                inline_formset = FormSet()
    434441                inline_formsets.append(inline_formset)
    435442
     
    467474        if request.POST and request.POST.has_key("_saveasnew"):
    468475            return self.add_view(request, form_url='../../add/')
    469476
    470         ModelForm = forms.form_for_instance(obj, formfield_callback=self.formfield_for_dbfield)
     477        ModelForm = forms.form_for_instance(obj, formfield_callback=lambda f: self.formfield_for_dbfield(f, request))
    471478
    472479        inline_formsets = []
    473480        if request.POST:
     
    475482            if opts.has_field_type(models.FileField):
    476483                new_data.update(request.FILES)
    477484            form = ModelForm(new_data)
    478             for FormSet in self.get_inline_formsets():
     485            for FormSet in self.get_inline_formsets(request):
    479486                inline_formset = FormSet(obj, new_data)
    480487                inline_formsets.append(inline_formset)
    481488
     
    483490                return self.save_change(request, model, form, inline_formsets)
    484491        else:
    485492            form = ModelForm()
    486             for FormSet in self.get_inline_formsets():
     493            for FormSet in self.get_inline_formsets(request):
    487494                inline_formset = FormSet(obj)
    488495                inline_formsets.append(inline_formset)
    489496
     
    610617        ]
    611618        return render_to_response(template_list, extra_context, context_instance=template.RequestContext(request))
    612619
    613     def get_inline_formsets(self):
     620    def get_inline_formsets(self, request):
    614621        inline_formset_classes = []
    615622        for opts in self.inlines:
    616             inline = inline_formset(self.model, opts.model, formfield_callback=opts.formfield_for_dbfield, fields=opts.fields, extra=opts.extra)
     623            inline = inline_formset(self.model, opts.model, formfield_callback=lambda f: opts.formfield_for_dbfield(f, request), fields=opts.fields, extra=opts.extra)
    617624            inline_formset_classes.append(inline)
    618625        return inline_formset_classes
    619626
Back to Top