Open benmaier opened 4 years ago
I solved this. One has to write a custom django_select2
-Widget, then override the form and override the CRUDview
.
I'm keeping this issue open though as I suspect that either of the following options would help other users:
autocomplete_fields
-property in the CRUDView
-class can take care of this. I feel as if this should not be too hard but I'm a beginner with django so it's hard for me to judge.I've based the following solution on these links:
myproject/urls.py
First, you have to register select2 in your projects/urls.py
as
from django.urls import path, include
urlpatterns = [
...
path('select2/', include('django_select2.urls')),
...
]
because select2 needs its own API to submit searchqueries.
myapp/views.py
The file is split so I can describe what's going on
from django import forms
from cruds_adminlte.crud import CRUDView
from django_select2.forms import ModelSelect2MultipleWidget, ModelSelect2Widget
from .models import Institution
First, we import cruds_adminlte
's CRUDview so we can adjust the view. Then, we import ModelSelect2MultipleWidget
, ModelSelect2Widget
which handle Select2-selects
in an asynchronous manner. Subsequently, we import the Model Institution
for which we want the autocomplete-fields.
class SingleSelectWidget(ModelSelect2Widget):
def filter_queryset(self, request, term, queryset, **dependent_fields):
qs = super().filter_queryset(request, term, queryset, **dependent_fields)
return qs.order_by(*self.ordering)
class MultipleSelectWidget(ModelSelect2MultipleWidget):
def filter_queryset(self, request, term, queryset, **dependent_fields):
qs = super().filter_queryset(request, term, queryset, **dependent_fields)
return qs.order_by(*self.ordering)
class SingleGeonameSelectWidget(SingleSelectWidget):
search_fields = ['name__icontains']
ordering = ['-population']
class MultipleGeonameSelectWidget(MultipleSelectWidget):
search_fields = ['name__icontains', 'englishname__icontains']
ordering = ['-population']
The first two classes are helper classes that allow their children to just define the ordering
property for filtering the search query, as one is used to from the admin-pages.
Now define a new form that uses the adjusted widgets:
class InstitutionForm(forms.ModelForm):
class Meta:
model = Institution
exclude = [] # tell django that all fields should be rendered
widgets = {
'city': SingleGeonameSelectWidget,
'responsible_for_places': MultipleGeonameSelectWidget,
}
Use this form to override the CRUDView property:
class InstitutionView(CRUDView):
model = Institution
add_form = InstitutionForm
update_form = InstitutionForm
myapp/urls.py
Register this Model's url
from django.urls import path, include
from django.conf.urls import url
from . import views
urlpatterns = [
url('', include(views.InstitutionView().get_urls())),
]
Another problem: the connection does not time out for the add_form
, it still does, however, for the update_form
Edit: I misspelled update_form
in the original solution. I've edited the solution above and it works now.
First, thanks for the package, looking really great! I've tested a few features that worked quite well, but I have a particular problem:
Several of my models refer with a ForeignKey to a geo-database that has ~350,000 entries. I've let
django-cruds-adminlte
auto-create all CRUD pages. Whenever I'm trying to load a create/update page of a model that references the foreign key to the geo-database, the connection times out. I have had this problem before with the default django-admin page and it was caused by the model page trying to load all 350,000 entries into the select (see e.g. this StackOverflow). I'm suspecting something similar is happening here.For the default admin page, this can be fixed by adding the
autocomplete_fields
attribute to the respectiveModelAdmin
, which tells the ModelAdmin that a particular field is to be searched asynchronously, and the way it is to be searched is defined in theModelAdmin
of the referencedModel
.Here's an example for the models:
Using these models to auto-generate CRUDS, the create-page of
Institution
times out.Here's how this is solved in the default admin-framework:
Which basically tells django "If a user wants to add a city to an institution, do not load all geoname-values in the select, rather do an Ajax request to the
Geoname
-table which is searched in the fieldsname
and decreasingly order the search results by the fieldpopulation
. Also, paginate the returned list".Is there a way to achieve this using
django-cruds-adminlte
? I've searched the documentation and the github-issues but could not find anything to achieve this.Cheers
Edit: Forgot 'population' entry in
Model
definition.