【问题标题】:What is the replacement for modelform_factory in the newest version of Django autocomplete light?在最新版本的 Django 自动完成灯中,modelform_factory 的替代品是什么?
【发布时间】:2016-07-18 13:17:56
【问题描述】:

在以前版本的自动完成灯中,有一种添加新表单的非常快速的方法。

form = modelform_factory(ModelName, fields='__all__')

如果模型注册了一个自动完成视图,这将根据给定的模型自动构建一个新表单。非常快速和容易。在今天发布的最新版本 3.1.6 中,此功能似乎已被删除。我不得不回去重做一切以使我们升级,我想知道我刚刚错过的新版本中是否有类似旧的modelform_factory。或者有没有一种快速的方法来设置一个可以轻松重用的通用自动完成视图/表单?任何想法表示赞赏。

【问题讨论】:

    标签: jquery django modelform django-autocomplete-light


    【解决方案1】:

    所以经过大量的搜索,我找不到任何类似于以前的自动完成灯光 modelform_factory 的东西,所以我决定自己制作。以下是直接取自我们生产 CMS 中的示例。

    from dal import autocomplete
    
    from mymodels import ThisModel, ThatModel, AnotherModel
    
    def autocomplete_form_factory(ac_model, *args, **kwargs):
        field_url_dict = {}
        m2m = ('mypeeps', 'yourpeeps',)
        if ac_model in (ThisModel, ThatModel):
            # Connects the "stuff_field" of these
            # models to the url named "stuff-autocomplete"
            field_url_dict = {
                'stuff_field': 'stuff'
            }
        elif ac_model == AnotherModel:
            # Connects AnotherModel's ForeignKey field "headhoncho"
            # and its ManyToManyFields "mypeeps" and "yourpeeps"
            # to the "peeps-autocomplete" url
            field_url_dict = {
                'headhoncho': 'peeps',
                'mypeeps': 'peeps',
                'yourpeeps': 'peeps',
            }
    
        # Assign the appropriate widgets based on this model's autocomplete dictionary
        ac_widgets = {}
        ac_fields = kwargs.get('fields', ('__all__'))
        for field, url in field_url_dict.iteritems():
            is_m2m = field in m2m
            text = 'Type to return a list of %s...' if is_m2m else 'Type to return a %s list...'
            kwargs = {
                'url': '%s-autocomplete' % url,
                'attrs': {
                    'data-placeholder': text % ac_model._meta.get_field(field).verbose_name,
                    'data-minimum-input-length': 3,
                }
            }
            ac_widgets[field] = autocomplete.ModelSelect2Multiple(**kwargs) if is_m2m else autocomplete.ModelSelect2(**kwargs)
    
        # Create the form
        class DynamicAutocompleteForm(forms.ModelForm):
            class Meta:
                model = ac_model
                fields = ac_fields
                widgets = ac_widgets
    
        return DynamicAutocompleteForm
    

    对于相应的视图,您可以按照以下方式进行操作:

    class BaseAutocomplete(autocomplete.Select2QuerySetView):
        model = None
        fields = ['title']
        filters = {}
    
        def get_queryset(self):
            if not self.request.user.is_authenticated() or not self.q or len(self.q) < 3:
                return self.model.objects.none()
    
            # OR all of our field searches together
            obj = Q()
            for field in self.fields:
                kwargs = {}
                kwargs['%s__icontains' % field] = self.q
                obj = obj | Q(**kwargs)
    
            return self.model.objects.filter(obj).filter(**self.filters)
    
    class StuffAutocomplete(BaseAutocomplete):
        model = Stuff
        filters = {'is_awesome': True}
    
    class PeepsAutocomplete(BaseAutocomplete):
        model = Peeps
        fields = ['name', 'notes']
    

    对于网址,您可以使用以下内容:

    url(r'^stuff-autocomplete/$', StuffAutocomplete.as_view(), name='stuff-autocomplete'),
    url(r'^peeps-autocomplete/$', PeepsAutocomplete.as_view(), name='peeps-autocomplete',),
    

    要在您的代码中使用表单工厂,您可以使用以下内容,将结果分配给模型管理员的表单或将其用作更复杂表单的基础:

    autocomplete_form_factory(ThisModel)
    autocomplete_form_factory(AnotherModel, fields=["headhoncho", "mypeeps"])
    

    这模仿了我们在自动完成早期 modelform_factory 中的功能,使得创建自动完成表单并在完成所有设置后根据需要将它们添加到管理员变得非常简单。希望这将有助于节省一些时间。

    【讨论】:

      猜你喜欢
      • 2016-12-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-03-25
      相关资源
      最近更新 更多