"""Autocomplete fields for Select2GenericForeignKey choices."""
from dal_queryset_sequence.fields import QuerySetSequenceModelField
from dal_select2_queryset_sequence.views import Select2QuerySetSequenceAutoView
from dal_select2_queryset_sequence.widgets import QuerySetSequenceSelect2
from django.urls import re_path as url
from queryset_sequence import QuerySetSequence
[docs]
class Select2GenericForeignKeyModelField(QuerySetSequenceModelField):
"""
Select2GenericForeignKeyModelField class.
Field that generate automatically the view for the
QuerySetSequenceSelect2 widget
"""
def __init__(self, *args, **kwargs):
"""
Initialize Select2GenericForeignKeyModelField.
:param args:
:param model_choice:
[(Model, 'filter_by', [('forwardfield_name', 'filter_by')]), ],
List of tuples, for each select2 widget. Model is the model to
query, 'filter_by' the attribute of the model to apply the filter.
The list in the tuple is optional, its to forward a field from the
form to the widget.
:param field_id: Optional name instead of the automatic one
:param kwargs:
"""
model_choice = kwargs.pop('model_choice', None)
field_id = kwargs.pop('field_id', None)
self.field_id = field_id if field_id else id(self)
if model_choice:
self.model_choice = model_choice
models_queryset = [model[0].objects.all()
for model in model_choice]
kwargs['queryset'] = QuerySetSequence(*models_queryset)
super(Select2GenericForeignKeyModelField, self).__init__(*args, **kwargs)
[docs]
def as_url(self, form):
"""Return url."""
url_name = '{}_autocomp_{}'.format(form.__name__, self.field_id)
forward_fields = {
forward_tuple[0]
for field in self.model_choice if len(field) > 2
for forward_tuple in field[2]
}
# a set of the fields to forward.
# it checks if the 3rd index of the list exists
self.widget = QuerySetSequenceSelect2(
url=url_name, forward=forward_fields
)
# generate the class to work with multiple gfk
# (can't work on instance level)
auto_view = type(
'Autoview{}{}'.format(form.__name__, self.field_id),
(Select2QuerySetSequenceAutoView,),
{'model_choice': self.model_choice}
) # send to the view the model and filter list
return url(
r'^{}_{}_autocomp$'.format(form.__name__, self.field_id),
auto_view.as_view(),
name=url_name
)