Also nach viel Jagd konnte ich nichts finden, das dem vorhergehenden modellform_factory des Autocomplete-Lichtes ähnelt, also entschied ich mich, mein eigenes zu machen. Das Folgende ist ein Beispiel, das direkt von dem stammt, was wir in unserem Produktions-CMS haben.
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
Für die entsprechenden Ansichten, könnten Sie etwas entlang der Linien der folgenden Aktionen:
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']
Und für Urls, könnte verwenden Sie Folgendes:
url(r'^stuff-autocomplete/$', StuffAutocomplete.as_view(), name='stuff-autocomplete'),
url(r'^peeps-autocomplete/$', PeepsAutocomplete.as_view(), name='peeps-autocomplete',),
zu bedienen Wenn Sie die Formularfactory in Ihrem Code verwenden, verwenden Sie etwas wie das Folgende, weisen die Ergebnisse dem Formular eines Formularadministrators zu oder verwenden es als Basis für ein komplexeres Formular:
autocomplete_form_factory(ThisModel)
autocomplete_form_factory(AnotherModel, fields=["headhoncho", "mypeeps"])
Dies ahmt die funcitonality wir mit der automatischen Vervollständigung früheren modelform_factory hatte, ist es sehr einfach machen automatische Vervollständigungen zu erstellen und diese an den Administrator nach Bedarf hinzufügen, nachdem alles eingerichtet zu werden. In der Hoffnung, dass dies helfen wird, jemanden Zeit zu sparen.